Contents
Item43. 람다보다는 메서드 참조를 사용하라.
   Feb 21, 2023     3 min read

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

✅핵심 정리

  • 메소드 참조는 람다의 간단명료한 대안이 될 수 있다.
  • 메소드 참조를 사용하여 짧고 명확하면 메서드 참조를 사용, 그렇지 않고 람다쪽이 더 짧고 명확할 경우 람다를 사용해라.

⚓️서론

저자는 람다가 익명 클래스보다 나은 점 중에서 가장 큰 특징은 간결함이라고 한다.

하지만 자바에서는 함수 객체를 람다보다도 더 간결하게 만드는 방법이 있다고 한다.

그 방법은 메소드 참조(method refernce)라고한다.


➡️임의의 키와 Integer 값의 매핑을 관리하는 프로그램의 일부.

  • 이때 값이 키의 인스턴스 개수로 해석된다면, 이 프로그램은 멀티셋(multiset)을 구현한 게 된다.
  • 이 코드는 키가 맵 안에 없다면 키와 숫자 1을 매핑하고, 이미 있다면 기존 매핑 값을 증가시킨다.
map.merge(key, 1, (count, incr) -> count + incr);

➡️merge 메소드 내부

  • merge메소드는 키, 값 , 함수를 인수로 받으며, 주어진 키가 맵 안에 아직 없다면 주어진 {키,값} 쌍을 그대로 저장한다.
  • 반대로 키가 이미 있다면(세 번째 인수로 받은)함수를 현재 값과 주어진 값에 적용한 다음, 그 결과로 현재 값을 덮어쓴다.
  • 간단히 말해서 맵에 {키, 함수의 결과}쌍을 저장한다.

Untitled

위 코드(맨 처음 코드)를 보면 보기 흉한 부분이 있다.

매개변수 count와 incr은 크게 하는 일이 없이 공간을 차지한다. → 람다는 두 인수의 합을 단순히 반환할 뿐이다..

  • Java8이 되면서 모든 기본 타입의 박싱 타입은 람다와 기능이 같은 정적 메소드 sum을 제공하기 시작했다.

따라서 람다 대신 메소드의 참조를 전달하면 똑같은 결과를 더 보기 좋게 얻을 수 있다.

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

➡️메소드 참조를 사용하는 경우 - 생각할 것들

  • 매개변수 수가 늘어날수록 메서드 참조로 제거할 수 있는 코드의양도 늘어난다. 라는 생각
  • 매개변수의 이름 자체가 프로그래머에게 좋은 가이드가 되기도 한다. 이런 람다는 길이는 더 길지만 메서드 참조보다 읽기 쉽고 유지보수도 쉬울 수 있다. 라는 생각
  • 람다로 할 수 없는 일이면 메서드 참조로도 할 수 없다. 라는 생각

➡️람다가 메서드 참조보다 간결한 경우

예를 들어) 코드가 GoshThisClassNameIsHumongous 클래스 안에 있다고 가정해보면

  • 메소드 참조로 표현할 경우
service.execute(GoshThisClassNameIsHumongous::action);
  • 람다로 표현할 경우
service.execute(() -> action());

위 코드를 비교해보면 메소드 참조를 표현한 코드가 더 길고 가독성이 더 좋지 않다. 이럴 경우는 람다로 표현하는 것이 더 좋다.


➡️메서드 참조의 유형 5가지

| 메서드 참조 유형 | 예 | 같은 기능을 하는 람다 | | — | — | — | | 정적 | 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] | —

➡️인스턴스 메서드를 참조하는 두 가지 유형

  1. 수신 객체(receiving object; 참조 대상 인스턴스)를 특정하는 한정적(bound)인스턴스 메서드 참조
  2. 수신 객체를 특정하지 않는 비한정적(unbound)인스턴스 메서드 참조
  • 한정적 인스턴스 메소드
    • 근본적으로 정적 참조와 유사하다.
    • 함수 객체가 받는 인수와 참조되는 메소드가 받는 인수가 똑같다.
  • 비한정적 인스턴스 메소드
    • 함수 객체를 적용하는 시점에서 수신 객체를 알려준다.
    • 이를 위해 수신 객체 전달용 매개변수가 매개변수 목록의 첫 번째로 추가되며, 그 뒤로는 참조되는 메소드 선언에 정의된 매개변수들이 뒤따른다.
    • 주로 스트림 파이프라인에서의 매핑과 필터 함수에 쓰인다.(아이템 45)
  • 참고

수신 객체를 특정하는 한정적(bound)인스턴스 메소드 참조 와 수신 객체를 특정하지 않는 비한정적(unbound)인 스턴스 메소드 참조 차이