참고
메서드 참조
NOTE
메서드 참조는 자바 8 코드의 람다 표현식에서 단 하나의 메소드를 호출하는 경우, 불필요한 매개변수를 제거할 수 있도록 한다!
// 기존의 람다 표현식
inventory.sort((Apple a1, Apple a2)
-> a1.getWeight().compareTo(a2.getWeight()));
// 메서드 참조와 java.util.Comparator.comparing을 활용한 코드
inventory.sort(comparing(Apple::getWeight));
Java
복사
매개변수가 사라지고, 어떤 메서드인지만 나타나게됨
메서드 참조의 3가지 유형
정적 메서드 참조
다양한 형식의 인스턴스 참조
기존 객체의 인스턴스 메서드 참조
메서드 참조 예시
NOTE
ToIntFunction<String> stringToInt = (String s) -> Integer.parseInt(s);
BiPredicate<List<String, String>> contains = (list, element) -> list.contains(element);
Predicate<String> startsWithNumber = (String string) -> this.startsWithNumber(string);
Java
복사
다음 람다 표현식을 메서드 참조로 바꿔봐라!
정답
생성자 참조
NOTE
클래스의 생성자를 이용해 참조를 만들어보자!
Supplier<Apple> c1 = Apple::new; // Apple()인 디폴트 생성자 참조
Apple a1 = c1.get(); // Supplier의 get 메서드를 호출해서 새로운 Apple 객체를 만들 수 있다.
// 위 코드는 다음과 같다.
Supplier<Apple> c1 = () -> new Apple();
Java
복사
생성자 역시 메서드 참조로 만들 수 있다.
Function<Integer, Apple> c2 = Apple::new; // Apple(Integer weight)의 생성자 참조
Apple a2 = c2.apply(110); // Function의 apply 메서드에 무게를 인수로 호출해서 새로운 Apple 객체를 만들 수 있다.
// 위 코드는 다음과 같다.
Function<Apple> c2 = (weight) -> new Apple(weight);
Java
복사
인지가 있어도 크게 다를건 없음
람다, 메서드 참조 활용하기
NOTE
사과 리스트 정렬 문제를 해결하면서 지금까지 배운 단계를 모두 활용해보자!
1. 코드 전달 (동작 파라미터화)
// sort에 전달할 정렬 전략을 가진 Comparator 구현 클래스
public class AppleComparator implements Comparator<Apple> {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
}
inventory.sort(new AppleComparator());
Java
복사
List sort에 활용한 Comparator 사용
2. 익명 클래스 사용
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
});
Java
복사
3. 람다 표현식 사용
inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight());
Java
복사
Comparator 사용방식
inventory.sort(Comparator.comparing(Apple::getWeight));
Java
복사
Comparator의 정적 메서드 comparing 사용
4. 메서드 참조 사용
inventory.sort(comparing(Apple::getWeight));
Java
복사
람다 표현식을 조합할 수 있는 유용한 메서드
NOTE
Java 8 API의 몇몇 함수는 람다 표현식을 조합할 수 있도록 유틸리티 메서드를 제공한다!
•
여러 개의 람다 표현식을 조합해서 복잡한 람다 표현식을 사용할 수 있다.
•
디폴트 메서드(default method)가 이를 가능하게 해줌!
Comparator 조합
NOTE
Comparator<Apple> c = Comparator.comparing(Apple::getWeight);
Java
복사
비교에 사용할 key를 추출하는 Function기반의 Comparator를 반환함
inventory.sort(comparing(Apple::getWeight)
.reversed()
.thenComparing(Apple::getCountry));
Java
복사
무게가 같은 두 사과가 존재한다면 다른 정렬 조건이 필요할 수 있다!
thenComparing은 2번째 비교자를 만들 수 있다.
Predicate 조합
NOTE
// 기존 프레디케이트 객체 redApple의 결과를 반전시킨 객체를 만든다.
Predicate<Apple> notRedApple = redApple.negate();
// 두 프레디케이트를 연결해서 새로운 프레디케이트 객체를 만든다.
Predicate<Apple> redAndHeavyApple = redApple.and(apple -> apple.getWeight() > 150);
// 프레디케이트 메서드를 연결해서 더 복잡한 프레디케이트 객체를 만든다.
Predicate<Apple> redAndHeavyAppleOrGreen = redApple.and(apple -> apple.getWeight() > 150)
.or(apple -> GREEN.equals(a.getColor()));
Java
복사
negate, and, or의 연산을 해준다.
Function 조합
NOTE
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g); // 수학으로는 write g(f(x)) 또는 (g ∘ f)(x)라고 표현
int result = h.apply(1); // 4를 반환
Java
복사
andThen → 주어진 함수를 먼저 적용하고, 다른 함수 입력으로 넘겨줌
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.compose(g); // 수학으로는 f(g(x)) 또는 (f ∘ g)(x)라고 표현
int result = h.apply(1); // 3을 반환
Java
복사
메서드 인수로 주어진 함수를 먼저 실행