람다의 메서드 참조

반응형
728x90
반응형

메서드 참조

메서드 참조를 이용하면 기존의 메서드 정의를 재활용해서 람다처럼 전달할 수 있다.

 

inventory.sort(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

 

위 코드를 메서드 참조와 java.util.Comparator.comparing을 활용한 코드로 바꿔보자.

// 메서드 참조의 사용
// Apple 클래스에 정의된 getWeight의 메서드 참조
// 실제로 메서드를 호출하는 것이 아니므로 괄호 생략
// 결과적으로 (Apple a) -> a.getWeight()를 축약한 것
inventory.sort(comparing(Apple::getWeight)); // = (Apple a) -> a.getWeight()

 

위 생소한 문법을 이해하기 전에, 우선 메서드 참조의 중요성에 대해 알아보자. 메서드 참조는 특정 메서드만을 호출하는 람다의 축약형이라고 생각할 수 있다. 람다가 메서드를 직접 호출하는 것 보다는 메서드명을 직접 참조하는 것이다. 실제로 메서드 참조를 이용하면 기존 메서드 구현으로 람다 표현식을 만들 수 있다.

 

메서드 참조의 문법을 이해하기

1) (Apple apple) -> apple.getWeight() : Apple::getWeight
2) () -> Thread.currentThread.dumpStack() : Thread.currentThread()::dumpStack()
3) (str, i) -> str.substring(i) : String::substring
4) (String s) -> System.out.println(s) : System.out::println
5) (String s) -> this.isValidName(s) : this::isValidName

 

 

메서드 참조 유형

1) 정적 메서드 참조

예시로 Integer의 parseInt 메서드는 Integer::parseInt로 표현할 수 있다.

 

2) 다양한 형식의 인스턴스 메서드 참조

  • 예시로 String의 lenth 메서드는 String::length로 표현할 수 있다.
(Stirng s) -> s.toUpperCase() : String::toUpperCase

 

3) 기존 객체의 인스턴스 메서드 참조

  • 예시로 Transaction 객체를 할당하는 expensiveTransaction 지역변수가 있고, Transaction 객체에는 getValue 메서드가 있다면 이를 expensiveTransaction::getValue라고 표현할 수 있다.
() -> expensiveTransaction.getValue() : expensiveTransaction::getValue

 

 

 

생성자 참조

ClassName::new 처럼 클래스명과 new 키워드를 사용하여 기존 생성자의 참조를 만들 수 있다. ClassName::new 를 사용하여 인스턴스를 만들고 해당 인스턴스를 사용하여 메서드를 호출할 수 있다. 또는 아래 예제처럼 Supplier 인스턴스를 생성하고 Supplier의 get 메서드를 통하여 새로운 객체를 생성할 수 있다.

Supplier<Height> h1 = Height::new; // 생성자의 참조
Height c1 = h1.get(); // Supplier 클래스의 get 메서드를 호출하여 새로운 Height 객체를 만든다.

 

만약, 매개변수가 3개인 생성자 참조를 사용하려면?

Heiht(int, int, int)
생성자 참조 문법은 ClassName::new 이므로 Height::new가 된다. 하지만 이를 사용하려면 생성자 참조와 일치하는 시그니처를 갖는 함수형 인터페이스가 필요한데, 이런 시그니처를 갖는 함수형 인터페이스가 존재하지 않으므로 우리가 직접 만들어야한다.

public interface HeightInterface<T, U, V, R> {
  R apply(T t, U u, V v);
}

 

위 함수형 인터페이스를 사용하여 아래처럼 생성자 참조를 할 수 있다.

HeightInterface<Integer, Integer, Integer, Height> height = Height::new;

 

반응형

'Coding > Java' 카테고리의 다른 글

스트림 구현  (0) 2020.11.06
스트림의 기본개념  (0) 2020.11.06
람다의 형식 검사, 형식 추론, 제약  (0) 2020.11.06
함수형 인터페이스 사용  (0) 2020.11.06
빌더 패턴의 권장 이유  (0) 2020.11.06

Designed by JB FACTORY