람다의 메서드 참조
- Coding/Java
- 2020. 11. 6.
메서드 참조
메서드 참조를 이용하면 기존의 메서드 정의를 재활용해서 람다처럼 전달할 수 있다.
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 |