포스트

Lambda

람다식(lambda expression)은 이름 없는 함수를 식 하나로 표현하는 문법이다. Java에서는 메서드가 하나뿐인 인터페이스의 구현을 짧게 쓰는 방법으로 동작한다. Java 튜토리얼은 람다식이 기능을 메서드 인자로, 코드를 데이터처럼 다룰 수 있게 해 준다고 설명한다 (Oracle).


왜 필요한가

람다식 이전에는 동작을 인자로 넘기려면 익명 클래스를 써야 했다. 정렬 기준이나 필터 조건처럼 한 줄짜리 로직도 클래스 선언, 메서드 시그니처, 중괄호를 모두 적어야 했다. 람다식은 컴파일러가 알 수 있는 부분을 생략해서 동작 자체만 남긴다.

1
2
3
4
5
6
7
8
9
10
// 익명 클래스
Comparator<String> byLength = new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return Integer.compare(a.length(), b.length());
    }
};

// 람다식
Comparator<String> byLength2 = (a, b) -> Integer.compare(a.length(), b.length());

문법

람다식은 괄호 안의 매개변수 목록, 화살표 ->, 본문으로 이루어진다.

  • 매개변수 타입은 생략할 수 있다.
  • 매개변수가 하나면 괄호도 생략할 수 있다. p -> p.getAge() >= 18
  • 본문이 식 하나면 그 값이 반환된다. 문장 여러 개라면 중괄호로 감싸고 return을 쓴다.
1
2
3
4
5
6
7
Predicate<Integer> isAdult = age -> age >= 18;
Function<String, Integer> length = s -> s.length();
Consumer<String> printer = s -> System.out.println(s);
BinaryOperator<Integer> add = (a, b) -> {
    int sum = a + b;
    return sum;
};

함수형 인터페이스와 타깃 타입

람다식은 혼자서는 타입이 없다. 컴파일러는 람다식이 놓인 위치(변수 선언, 대입, 반환문, 메서드 인자 등)가 기대하는 타입, 곧 타깃 타입을 보고 어떤 인터페이스의 구현인지 정한다. 이때 타깃이 될 수 있는 것이 함수형 인터페이스다. 튜토리얼의 정의로는 추상 메서드가 정확히 하나인 인터페이스이고, default 메서드나 static 메서드는 몇 개가 있어도 된다. 추상 메서드가 하나뿐이므로 람다식에서 메서드 이름을 생략할 수 있다.

java.util.function 패키지는 자주 쓰는 형태를 미리 정의해 둔다.

인터페이스메서드용도
Predicate<T>boolean test(T t)조건 검사, 필터
Consumer<T>void accept(T t)값을 받아 동작 수행
Function<T,R>R apply(T t)값을 다른 값으로 변환

본문이 기존 메서드 호출 하나뿐이라면 String::length, System.out::println 같은 메서드 참조로 더 줄일 수 있다.


주의할 점

  • 람다식은 바깥 블록의 지역 변수와 매개변수 중 final이거나 사실상 final(effectively final)인 것만 읽을 수 있다. 초기화 이후 값을 바꾸는 변수를 참조하면 컴파일 오류가 난다.
1
2
int count = 0;
list.forEach(s -> count++); // 컴파일 오류: effectively final이 아니다
  • 람다식은 렉시컬 스코프를 따른다. 새로운 스코프를 만들지 않으므로 바깥 지역 변수와 같은 이름의 매개변수를 선언할 수 없고, 본문의 this는 람다식을 감싼 객체를 가리킨다. 익명 클래스의 this가 익명 클래스 자신을 가리키는 것과 다르다.
  • 람다식은 짧을 때 읽기 쉽다. 본문이 길어지면 이름 있는 메서드로 빼고 메서드 참조로 넘기는 편이 낫다.
참고한 자료외부 출처 2 · 블로그 글 2

외부 출처

이 블로그의 관련 글

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다