메소드 참조, 생성자 참조

메소드 참조(method reference)

람다 표현식이 단 하나의 메소드만을 호출하는 경우에 해당 람다 표현식에서 불필요한 매개변수를 제거하고 사용 메소드 참조를 사용하면 불필요한 매개변수를 제거하고 다음과 같이 ‘::’ 기호를 사용하여 표현

문법

클래스이름::메소드이름
참조변수이름::메소드이름

예제

다음 예제는 두 개의 값을 전달받아 제곱 연산을 수행하는 Math 클래스의 클래스 메소드인 pow() 메소드를 호출하는 람다 표현식

(base, exponent) -> Math.pow(base, exponent);

위의 예제는 단순히 Math 클래스의 pow() 메소드로 인수를 전달하는 역할만 하므로, 메소드 참조를 사용하여 다음과 같이 간단히 표현할 수 있다.

Math::pow;
//1
DoubleUnaryOperator oper;

oper = (n) -> Math.abs(n); // 람다 표현식
System.out.println(oper.applyAsDouble(-5));

oper = Math::abs; // 메소드 참조
System.out.println(oper.applyAsDouble(-5));

//2
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())); // 람다 표현식
inventory.sort(compareTo(Apple::getWeight)); // 메서드 참조

메서드 참조는 세 가지 유형

1. 정적 메서드 참조
   // 람다 표현식
   ToIntFunction<String> stringToInt = (String s) -> Integer.parseInt(s);
   // 메서드 참조
   Function<String, Integer> stringToInteger = Integer::parseInt;
2. 다양한 형식의 인스턴스 메서드 참조
   // 람다 표현식
   BigPredicate<List<String>, String> contains = (list, element) -> list.contains(element);
   // 메서드 참조
   BigPredicate<List<String>, String> contains = List::contains;
3. 기존 객체의 인스턴스 메서드 참조
   // 람다 표현식
   Predicate<String> startsWithNumber = (String s) -> this.startsWithNumber(s);
   // 메서드 참조
   Predicate<String> startsWithNumber = this::startsWithNumber;

생성자 참조

ClassName::new 처럼 클래스명과 new 키워드를 이용해서 기존 생성자의 참조한다. 단순히 객체를 생성하고 반환하는 람다 표현식이다.

(a) -> { return new Object(a); }

위의 예제는 단순히 Object 클래스의 인스턴스를 생성하고 반환하기만 하므로, 생성자 참조를 사용하여 다음과 같이 간단히 표현할 수 있다.

Object::new;

다양한 예제

(Apple apple) -> apple.getWeigh()
Apple::getWeigh

() -> Thread.currentThread().dumpStack()
Thread.currentThread()::dumpStack

정리

동작 파라미터화를 람다 표현식을 사용해 가독성 좋게 구현하고, 이 람다 표현식을 메소드 참조와 생성자 참조를 사용하여 조금 더 가독성 좋게 코드를 구현할 수 있다.