람다 표현식 1

Travel·2023년 8월 9일

Java

목록 보기
4/5

람다 표현식

람다(Lambda)란?

람다 표현식은 메서드로 전달할 수 잇는 익명 함수를 단순화한 것이라고 할 수 있다. 람다 표현식에는 이름은 없지만, 파라미터 리스트, 바디, 반환 형식 발생할 수 있는 예외 리스트는 가질 수 있다.

특징

  • 익명
    보통의 메서드와 달리 이름이 없으므로 익명이라 표현. 구현해야할 코드에 대한 걱정거리가 줄어든다.
  • 함수
    람다는 메서드처럼 특정 클래스에 종속되지 않으므로 함수라고 부른다. 하지만 메서드처럼 파라미터 리스트, 바디, 반환형식, 가능한 예외 리스트를 포함한다.
  • 전달
    람다 표현식을 메서드 인수로 전달하거나 볍ㄴ수로 저장할 수 있다.
  • 간결성
    익명 클래스처럼 많은 자잘구레한 코드를 구현할 필요가 없다.

람다가 중요한 이유는 앞에서 코드를 전달하는 과정에서 불필요한 많은 코드가 생기고, 람다로 이 문제를 해결할 수 있었다.
즉 람다를 이용하면 코드가 간결하고 유연해진다

Comparator<Apple> byWeight = new Comparator<Apple>() {
    public int comparator(Apple a1, Apple a2) {
            return a1.getWeight().compareTo(a2.getWeight());
        }
};

람다를 이용한 코드

Comparator<Apple> byWeight =
        (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

해당 구문이 람다 표현식이며 파라미터, 화살표, 바디로 이루어진다.

(Apple a1, Apple a2) → a1.getWeight().compareTo(a2.getWeight())

  • 파라미터 리스트
    Comparator의 compare 메서드 파라미터 : (Apple a1, Apple A2)
  • 화살표
    화살표 (→) 는 람다의 파라미터 리스트와 바디를 구분한다.
  • 람다 바디
    두 사과의 무게를 비교한다, 람다의 반환값에 해당하는 표현식이다.

규칙

  • 메서드 이름과 반환 타입의 경우에는 생략 가능하다.
  • 매개변수의 타입을 추론할 수 있는 경우 타입을 생략할 수 있다.(대부분 생략가능)
  • 매개변수가 하나인 경우에는 괄호(())를 생략할 수 있다.

    str -> {System.out.println(str)};

    • 두개 이상인 경우 사용불가
      (x,y) -> {System.out.println(x+y)};
  • 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략할 수 있다. (return문은 사용 불가능)

    str -> System.out.println(str);

  • 구현문이 한문장이더라도 return문은 생략 불가능

    str -> return str.length();

  • 구현문이 return문 하나라면 중괄호와 return문 모두 생략하고 식만 작성

    str -> str.length();

람다 사용

람다는 함수형 인터페이스라는 문맥에서 사용할 수 있다.

함수형 인터페이스란?

정확히 하나의 추상 메서드를 지정하는 인터페이스를 함수형 인터페이스라고 한다.

public interface Predicate<T> {
    boolean test(T t);
}

public interface Comparator<T> {
    int compare(T o1, T o2);
}

public interface Runable {
    void run();
}

public interface ActionListener extends EventListnenr {
    void actionPerformed(ActionEvent e);
}

public  interface callable<V> {
    V call() throws Exception;
}

public interface PrivilegedAction<T> {
    T run();
}

많은 디폴트 메서드가 있더라고 추상 메서드가 오직 하나면 함수형 인터페이스다.

함수형 인터페이스를 사용하면 람다 표현식으로 함수형 인터페이스의 추상 메서드 구현을 직접 전달할 수 있으므로
전체 표현식을 함수형 인터페이스의 인스턴스로 취급(기술적으로 따지면 함수형 인터페이스를 구현한 클래스의 인스턴스)할 수 있다.

Runnable r1 = () -> System.out.println("Hellow world 1") // 람다 사용

Runnable r2 = new Runnable() {    // 익명 클래스 사용
    public void run() {
        System.out.println("Hellow world 2");
        }
}

public static void process(Runnable r) {
    r.run();
}

process(r1);
process(r2);
process(() -> System.out.println("Hellow world 3")); // 직접 전달된 람다 표현시긍로 'Hellow world 3' 출력

함수 디스크립터

함수형 인터페이스의 추상 메서드 시그니처는 람다 표현식의 시그니처를 가리킨다. 람다 표현식의 시그니처를 서술하는 메서드를 함수 스크립터 라고 부른다.
예를 들어, Runnable 인터페이스의 유일한 추상 메서드 run은 인수와 반환 값이 없으므로 (void 반환) Runnable 인터페이스는 인수와 반환값이 없는 시그니처로 생각할 수 있다.

출처
모던 자바 인 액션

0개의 댓글