[이펙티브 자바] 아이템 43. 람다보다는 메서드 참조를 사용하라

June·2022년 3월 15일
0

[이펙티브자바]

목록 보기
38/72
map.merge(key, 1, (count, incr) -> count + incr);

자바 8때 Map에 추가된 merge 메서드다. merge 메서드는 키, 값, 함수를 인수로 받으며 주어진 키가 맴 안에 아직 없으면 {키, 값} 쌍을 저장하고, 있으면 세 번째 인수로 받은 함수를 현재값과 주어진 값에 적용한 다음 그결과로 현재 값을 덮어쓴다.

깔끔해보이지만 람다 부분이 거추장스럽다. 이 람다는 두 인수의 합을 단순히 반환할 뿐이다. 자바 8이 되면서 Integer 클래스는 이 람다와 기능이 같은 정적 메서드 sum을 제공하기 시작했다.

map.merge(key, 1, Integer::sum);

매개변수 수가 늘어날 수록 메서드 참조로 제거할 수 있는 코드 양도 늘어난다.

만약 매개변수 이름이 드러나는게 가독성이 더 좋다면 람다를 써도 좋다.
또는 람다가 메서드 참조보다 간결할 때가 있는데, 메서드와 람다가 같은 클래스에 있을 때 그렇다.

service.execute(GoshThisClassNameIsHumongous::action); // 메서드 참조
service.execute(() -> action());

기본적으로 람다로 할 수 없는거는 메서드 참조로도 할 수 없다.

메서드 참조 다섯 가지 유형

1. 정적 메서드 참조

Integer::parseInt
str -> Integer.parseInt(str);

2. 한정적 인스턴스 메서드 참조

Instant.now()::isAfter
Instant then = Instant.now();
t -> then.isAfter(t);

수신 객체(참조 대상 인스턴스)를 특정하는 한정적 인스턴스 메서드 참조. 근본적으로 정적 참조와 비슷하다. 즉 함수 객체가 받는 인수와 참조되는 메서드가 받는 인수가 똑같다.

3. 비한정적 인스턴스 메서드 참조

String::toLowerCase
str -> str.toLowerCase()

수신 객체를 특정하지 않는 인스턴스 메서드 참조. 함수 객체를 적용하는 시점에 수신 객체를 알려준다.
주로 스트림 파이프라인에서의 매핑과 필터 함수에 쓰인다.

4. 클래스 생성자

TreeMap<K,V>::new
() -> new TreeMap<K,V>()

5. 배열 생성자

int[]::new
len -> new int[len]

예외

람다로는 불가능하나 메서드 참조로는 불가능한 유일한 예는 제네릭 함수 타입 구현. 재내릭 람다식이라는 문법이 존재하지 않는다.

참고

자바의 정석 - 람다식

0개의 댓글