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());
기본적으로 람다로 할 수 없는거는 메서드 참조로도 할 수 없다.
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]
람다로는 불가능하나 메서드 참조로는 불가능한 유일한 예는 제네릭 함수 타입 구현. 재내릭 람다식이라는 문법이 존재하지 않는다.