익명 이라 표현한다.함수라고 부른다.// 람다 이용 X
Comparator<Apple> byWeight = new Comparator<Apple>() {
@Override
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
}
// 람다 이용
Comparator<Apple> byWeight = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
파라미터 리스트 → Comparator의 compare 메서드 파라미터(사과 2개)
화살표 리스트 → 화살표는 람다의 파라미터 리스트와 바디를 구분
람다 바디 → 두 사과의 무게를 비교. 람다의 반환값에 해당하는 표현식.
(parameters) → expression (표현식 스타일)
(parameters) → { statements; } (블록 스타일)
return 문이 필요사용시 체크사항
() -> {}() -> "Raoul"() -> {return "Mario";}(Integer i) -> return "Alan" + i;return 키워드를 사용할 수 없습니다. 중괄호 {}가 없으면 return을 생략해야 합니다.(Integer i) -> "Alan" + i(String s) -> {"Iron Man";} (String s) -> { return "Iron Man"; } 또는 (String s) -> "Iron Man": 람다가 사용되는 콘텍스트를 이용해서 람다의 형식을 추론할 수 있다.어떤 콘텍스트에서 기대되는 람다 표현식의 형식을 대상 형식 이라고 부린다.
: 자바 컴파일러는 람다 표현식이 사용된 콘텍스트(대상 형식)를 이용해서 람다 표현식과 관련된 함수형 인터페이스를 추론한다.
함수 디스크립터 를 통해 람다의 시그니처를 추론할 수 있다.
// 형식 추론을 이용하지 않음
Comparator<Apple> c = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight));
// 형식 추론 이용
Comparator<Apple> c = (a1, a2) -> a1.getWeight().compareTo(a2.getWeight));
: 람다 표현식에서는 익명 함수가 하는 것처럼 자유 변수 를 활용할 수 있다. 이와 같은 동작을 람다 캡처링 이라고 부른다.
[ 제약사항 ]
final로 선언 되어 있어야 하거나 final 로 선언된 변수와 똑같이 사용되어야 한다.int portNumber = 8080;
Runnable r = () -> System.out.println(portNumber);
portNumber = 8081; // 에러 - 재할당 불가능, 상수취급
[ 설명 ]
인스턴수 변수 와 지역 변수 의 특성을 생각해보자.
인스턴스 변수 는 힙에 저장되는 반면 지역 변수 는 스택에 위치한다.
람다에서 지역 변수에 바로 접근할 수 있다는 가정하에 람다가 스레드에서 실행된다면 변수를 할당한 스레드가 사라져서 변수 할당이 해제 되었는데도 람다를 실행하는 스레드에서는 해당 변수에 접근하려 할 수 있다.
따라서 자바 구현에서는 원래 변수에 접근을 허용하는 것이 아니라 자유 지역 변수의 복사본을 제공한다.
따라서 복사본의 값이 바뀌지않아야 하므로 지역 변수에는 한 번만 값을 할당해야 한다는 제약이 생겼다.
: 특정 메서드만을 호출하는 람다의 축약형(:: 사용)
만드는 방법
정적 메서드 참조 - Interger의 parseInt 메서드는 Integer::parseInt로 표현
다양한 형식의 인스턴스 메서드 참조 - String::length
기존 객체의 인스턴스 메서드 참조
// 예제
private boolean isValidName(String name) {
return Character.isUpperCase(name.charAt(0));
}
// 사용
filter(words, this::isValidName)
책 - 모던 자바 인 액션
Claude.ai