JAVA/Effective Java

item 43. 람다보다는 메서드 참조를 사용하라

Garonguri 2022. 6. 17. 02:23
728x90

자바에서 함수를 간결하게 하는 방법!

 : 메서드 참조 > 람다 > 익명 클래스

 

Map의 merge 메소드를 통하여 예시를 살펴보자.

Map<Integer, Integer> map = new HashMap<>();
map.put(1, 2);
map.put(3, 4);
map.put(5, 6);

int key = 1;
map.merge(key, 2, (count, incr) -> count + incr);

[코드 설명]

  • Map 타입 객체에 key를 매핑한다.
  • Map 안에 key가 존재한다면, value와 기존 key에 매핑되는 value를 더한다.
  • 존재하지 않을 경우에는 key, value를 추가한다.

: 깔끔해 보이지만, 매개변수 count와 incr은 크게 하는 일 없이 공간을 많이 차지하기 때문에, 거추장스럽다.

: 또한 여기서 사용된 람다는 두 인수의 합을 반환하는 역할만을 한다. (비교적 가벼운 역할?)

 

위에서 사용된 람다와 같은 기능을 하는 정적 메서드 sum을 사용해 위 코드를 메서드 참조를 사용하도록 바꿔보자.

map.merge(key, 2, (count, incr) -> count + incr);

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

위와 같은 경우 매개 변수가 늘어날 수록 메서드 참조로 제거할 수 있는 코드의 양도 늘어나고, 따라서 더 간결해진다.


Q. 그럼 무조건 메서드 참조가 좋나?

A. 아니!

어떤 람다에서는 매개변수 이름 자체가 프로그래머에게 가이드(문서)이기도 하다. 따라서 람다가 더 길어도 유지보수나 가독성 면에서 더 좋기 때문에 이런 경우에는 람다를 사용하는 것이 좋다.

 

Q. 어떤 경우에 람다가 더 좋은데?

A. 메서드와 람다가 같은 클래스 내에 있을 때는, 람다가 메서드 참조보다 간결하다.

map.merge(key, 2, (count, incr) -> count + incr);

람다로 할 수 없는 일은 메서드 참조로도 할 수 없다.

따라서, 메서드 참조를 사용했을 때 더 간결하고 짧은 코드가 되고, 람다를 사용했을 경우 너무 길거나 복잡한 코드가 될 경우에는 메서드 참조를 사용해보자.

 

즉, 람다로 작성할 코드를 새로운 메서드에 담은 다음 그 메서드를 참조하는 식으로 사용하라는 말이다.

service.execute(GoshThisClassNameIsHumongous::action);

service.execute(() -> action());

메서드 참조의 유형은 다섯 가지이다.

 

메서드 참조 유형 같은 기능을 하는 람다 의미
정적(Static) 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]; 배열 생성자를 가리키는
메서드 참조,
팩터리 객체로 사용한다.
핵심 정리

메서드 참조가 짧고 명확하다면 메서드 참조를, 그렇지 않을 때는 람다를 사용해라!
728x90