자바에는 함수객체를 람다보다 더 간결하게 만드는 방법이 있음
⇒ 메서드 참조
// 람다 사용 : 매개변수 count, incr은 크게 하는 일이 없다
map.merge(key, 1, (count, incr) -> count + incr);
// 메서드 참조 사용
map.merge(key, 1, Integer::sum);
람다로 할 수 없는 일이라면 메서드 참조로도 할 수 없다
예외
// 메서드 참조로 제네릭 타입 구현
Comparator<Person> comparator1 = Comparator.comparing(Person::getName);
// 람다식으로 같은 작업을 구현하려고 하면 컴파일 오류 발생
Comparator<Person> comparator2 = Comparator.comparing(p -> p.getName()); // 컴파일 오류
함수형 인터페이스를 위한 제네릭 함수 타입은 메서드 참조 표현식으로는 구현할 수 있지만 람다식으로는 불가능 (타입을 추론할 수 없어서 ..)
대체로 메서드 참조를 사용하는 편이 더 짧고 간결
IDE들은 람다를 메서드 참조로 대체하라고 권하는데, 이를 따르는 게 보통은 이득이지만, 때로는 람다가 메서드 참조보다 간결할 때가 있음
// GoshThisClassNameIsHumongous 클래스 안에 있는 코드
service.excute(GoshThisClassNameIsHumongous::action);
service.execute(() -> action());
메서드 참조 유형 | 예 | 같은 기능 |
---|---|---|
정적 | Integer::parseInt | str -> Integer.parseInt(str) |
한정적(인스턴스) | Instance.now()::isAfter | Instance 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] |
한정적 메서드 참조
class Person {
String name;
public Person(String name) { this.name = name; }
public void sayHello() { System.out.println("Hello, " + name); }
}
public class Main {
public static void main(String[] args) {
Person person = new Person("Alice");
// 한정적 메서드 참조, 이미 존재하는 person 인스턴스에 바인딩된 메서드를 참조
Runnable r = person::sayHello;
r.run();
}
}
비한정적 메서드 참조
class Person {
String name;
public Person(String name) { this.name = name; }
public void sayHello() { System.out.println("Hello, " + name); }
}
public class Main {
public static void main(String[] args) {
Function<Person, String> getName = Person::getName; // 비한정적 메서드 참조
Person person = new Person("Alice");
System.out.println(getName.apply(person));
}
}