•
사과 리스트를 다양한 정렬 기법으로 정렬하는 문제로 다시 돌아가서 3장에서 배운 람다를 통해 이 문제를 더 세련되고 간결하게 해결하는 방법을 보여준다.
•
사과 리스트 정렬 문제를 해결하기 위해 지금까지 배운 동작 파라미터화, 익명 클래스, 람다 표현식, 메서드 참조 등을 총동원한다.
•
최종 목표는 다음과 같은 코드를 만드는 것이다.
inventory.sort(comparing(Apple::getWeight));
Java
복사
1. 1단계 : 코드 전달
•
다행히 자바 8의 List API에서 sort 메서드를 제공하므로 정렬 메서드를 직접 구현할 필요는 없다.
•
그런데 어떻게 sort 메서드에 정렬 전략을 전달할 것일까? 먼저 sort 메서드의 시그니처를 살펴보자. 다음과 같다.
void sort(Comparator<? super E> c)
Java
복사
•
이 코드는 Comparator 인터페이스의 객체를 인수로 받아 두 리스트를 정렬하는 기준으로 삼는다. 즉 sort에 전달된 정렬 전략에 따라 sort의 동작이 달라질 것이다.
•
1단계 코드는 다음과 같이 완성할 수 있다.
public class AppleComparator implements Comparator<Apple> {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
}
inventory.sort(new AppleComparator());
Java
복사
2. 2단계 : 익명 클래스 사용
: 한 번만 사용할 Comparator를 위 코드처럼 구현하여 선언하는 것보다는 익명 클래스를 이용하는 것이 좋다.
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
});
Java
복사
3. 3단계 : 람다 표현식 사용
: 하지만 아직도 코드가 꽤나 장황해 보인다. 자바 8에서는 람다 표현식이라는 경량화된 문법을 이용해서 코드를 전달할 수 있다.
: 함수형 인터페이스를 사용할 수 있는 곳 어디에서나 람다 표현식을 사용할 수 있음을 우리는 이미 알고 있다.
: 추상 메서드의 시그니처는 람다 표현식의 시그니처를 저의한다. Comparator의 함수 디스크립터는 (T, T) → int다. 우리는 사과를 정렬할 것이므로 (Apple, Apple) → int로 표현할 수 있다.
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));
Java
복사
: 여기서 자바 컴파일러는 람다 표현식이 사용된 컨텍스트를 활용해서 람다의 파라미터 형식을 추론한다고 설명했다. 따라서 코드를 다음과 같이 더 줄일 수 있다.
inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));
Java
복사
: 이 코드의 가독성을 더 향상시킬 수는 없을까? Comparator는 Comparable 키를 추출해서 Comparator 객체로 만드는 Function 함수를 인수로 받는 정적 메서드 comparing을 포함한다.
: 즉 다음처럼 comparing 메서드를 사용할 수 있다.
Comparator<Apple> c = Comparator.comparing((Apple a) -> a.getWeight());
Java
복사
: 이제 다음처럼 코드를 간소화할 수 있다.
import static java.util.Comparator.comparing;
inventory.sort(comparing(apple -> apple.getWeight()));
Java
복사
4. 4단계 : 메서드 참조 사용
: 메서드 참조를 이용하면 람다 표현식의 인수를 조금 더 깔끔하게 전달할 수 있다는 것도 설명햇다.
import static java.util.Comparator.comparing;
inventory.sort(comparing(Apple::getWeight));
Java
복사
: 드디어 최적의 코드에 도달했다. 자바 8 이전의 코드와 비교해서 뭐가 달라졌을까?
: 먼저 코드가 짧아졌다. 그리고 코드의 의미도 명확해졌다. 즉 코드 자체로 Apple을 weight 별로 비교해서 inventory를 sort하라는 의미를 전달할 수 있다.