람다가 익명 클래스보다 나은 점 중에서 가장 큰 특징은 간결함이다.
그렇지만 메소드 참조를 이용하면 함수객체를 람바보다 더 간결하게 만들 수 있다.
// 람다
map.merge(key, 1, (count, incr) -> count + incr);
// 메소드 참조
map.merge(key, 1, Integer::sum);
이 코드는 둘다 키가 맵 안에 있다면 키와 숫자 1을 매핑하고 이미 있다면 기존 매핑값을 증가시킨다.
자바 8에서는 Map 에 추가된 merge 메서드를 사용했다. merge 메서드는 ( 키, 값, 함수 ) 를 인자로 받아 주어진 키가 맵 안에 없다면 주어진 (키, 값) 쌍을 그대로 저장한다. 반대로 키가 이미 있다면 (함수) 를 현재값과 주어진 값에 적용한 다음 그 결과로 현재값을 덮어쓴다. 즉, 맵에 (키, 함수의 결과) 를 쌍으로 저장한다.
이렇게 메소드를 참조하는 편이 보통은 더 짧고 간결하므로, 람다로 구현했을 때 너무 길거나 복잡하다면 메소드 참조가 좋은 대안이 되어준다. 하지만 때때로 람다가 메소드 참조보다 간결할 때가 있다. 주로 메소드와 람다가 같은 클래스에 있을 때 그렇다.
아래의 예시를 보자.
service.execute(GoshTishClassNAmeIsHumongous::action);
//이를 람다로 대체하게 되면 아래와 같다.
service.execute(() -> action());
메소드 참조 쪽은 더 짧지도 더 명확하지도 않기 때문에 람다쪽이 더 낫다.
메소드 참조 유형은 다섯가지로 아래와 같다.
메소드 참조 유형 | 예 | 같은 기능을 하는 람다 |
정적 | Integer::parseInt | str -> Integer.parseInt(str) |
한정적(인스턴스) | Instant.now()::isAfter | Instant then = Instant.now(); t -> then.isAfter(t) |
비한정적(인스턴스) | String::toLowerCase | str -> str.toLowerCase() |
클래스 생성자 | TreeMap<K, V>::new | () -> new TreeMap<K,V>() |
배열 생성자 | int()::new | len -> new int[len] |
메소드 참조는 람다의 간단명료한 대안이 될 수 있다.
메소드 참조 쪽이 짧고 명확하다면 메소드 참조를 쓰고, 그렇지 않을 때만 람다를 사용하라
'BOOK > Effective Java' 카테고리의 다른 글
[Effec Java] Item.47 반환 타입으로는 스트림보다 컬렉션이 낫다 (0) | 2023.01.25 |
---|---|
[Effec Java] Item.46 스트림에서는 부작용 없는 함수를 사용하라 (0) | 2023.01.06 |
[Effec Java] Item.45 스트림은 주의해서 사용하라 (0) | 2023.01.04 |
[Effec Java] Item.44 표준 함수형 인터페이스를 사용하라 (0) | 2023.01.03 |
[Effec Java] Item.42 익명 클래스보다는 람다를 사용하라 (0) | 2022.10.21 |