람다보다는 메서드 참조를 사용하라
메서드 참조
map.merge(key, 1, (count, incr) -> count + incr);
위 코드는 Map의 merge 메서드를 사용했다. merge 메서드는 키, 값, 함수를 인수로 받으며, 주어진 키가 맵 안에 아직 없다면 주어진 키,값 쌍을 그래도 저장한다. 반대로 키가 이미 있다면 세 번째 인수로 받은 함수를 현재 값과 주어진 값에 적용한 다음, 그 결과로 현재 값을 덮어쓴다.
매개변수인 count와 incr은 크게 하는 일 없이 공간을 꽤 차지한다. 람다는 두 인수의 합을 반환할 뿐이다. 따라서 람다 대신 이 메서드의 참조를 전달하면 똑같은 결과를 더 보기 좋게 얻을 수 있다.
map.merge(key, 1, Integer::sum);
람다에서는 매개변수의 이름 자체가 프로그래머에게 좋은 가이드가 되기도 한다. 이 경우 람다가 더 길지만 메서드 참조보다 읽기 쉽고 유지보수도 쉬울 수 있다.
람다가 메서드 참조보다 간결할 때
주로 메서드와 람다가 같은 클래스에 있을 때 그렇다.
service.execute(GoshThisClassNameIsHumongous::action);
service.execute(() -> action()));
같은 예로 java.util.function 패키지의 제네릭 정적 팩터리 메서드인 Function.identity()
보다 (x -> x)
를 사용하는 편이 더 낫다.
메서드 참조 유형
메서드 참조 유형 | 예 | 람다 |
---|---|---|
정적 | 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] |
함수형 인터페이스의 추상 메서드가 제네릭일 수 있듯이 함수 타입도 제네릭일 수 있다. 함수형 인터페이스를 위한 제네릭 함수 타입은 메서드 참조 표현식으로는 구현할 수 있지만, 람다식으로는 불가능하다. 제네릭 람다식이라는 문법이 존재하지 않기 때문이다.
Comments