알고리즘을 풀며 Comparator 인터페이스를 사용할 때 주로 클래스로 구현하거나 익명 클래스를 사용하여 정렬을 하였다.
public class AppleComparator implements Comparator<Apple> {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(o2.getWegiht());
}
}
inventory.sort(new AppleComparator());
혹은
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight()-a2.getWeight();
}
});
이런 익명클래스를 이용하였다.
하지만 자바 8부터 람다가 나오면서 경량화된 문법을 이용할 수 있다. 람다는 함수형 인터페이스를 기대하는 곳 어디에서나 사용할 수 있다. Comparator는 compare 추상 메서드를 하나 갖고 있는 함수형 인터페이스이다. Comparator를 보면 equals이나 다른 메서드가 몇개 있는 것을 볼 수 있는데 이건 디폴트 메서드이거나 정적 메서드이므로 추상 메서드는 아니다.
람다는 이러한 함수형 인터페이스의 추상메서드를 구현하는 함수라고 생각하면 된다. 그렇기 때문에 추상 메서드의 시그니처 (리턴값, 인자값등 구현에 필수적인 요소라 생각하자!)는 람다 표현식의 시그니처를 정의한다. Comparator의 함수 디스크립터(추상 메서드의 시그니처)는 (T, T) -> int이다. 이를 람다를 사용해 표현하면
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())); 로 표현할 수 있다.
컴파일러는 람다의 파라미터 형식을 추론가능하다. 그러므로 이를 또
inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight())); 로 바꿀 수 있다.
여기에서 조금 더 욕심을 부려보자. 메서드 참조를 사용하면 이를 더 직관적인 코드로 변환시킬 수 있다. 그러기 위해서는 메서드 참조가 무엇인지 알아야 한다.
메서드 참조? 메서드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어 불필요한 선언부분을 줄이는 것
예시를 통해 이해해보자. 자바 사용자라면 모두 알만한 Math.max(int a, int b) 메서드를 보자. 이를 호출하는 람다식은 (int a, int b) -> Math.max(a,b)가 될 것이다. 이를 메서드 참조로 변경하면 Math::max가 된다. a,b라는 변수가 중복되고 있기에 삭제한 후 Math.max 와 같은 호출을 Math::max로 변경하여 사용한다.
IntBinaryOperator 함수형 인터페이스는 리턴값이 int이고 int형 매개변수를 두개 받는 추상 메서드(applyAsInt)를 갖고 있다. 위에서 본 Math::max와 그렇기 때문에 함수 디스크립터가 같다.
IntBinaryOperator a = Math::max;
a.applyAsInt(100,200);
때문에 위와 같은 형태로 사용 사용할 수 있다.
이를 기반으로 기존 코드를 변경하면 inventory.sort(comparing(Apple::getWeight));로 변경할 수 있다. 정말 직관적이고 간결한 코드가 되었다. 코드만 읽어도 어떤 일을 하는 것인지 명확히 이해를 할 수 있다. 정렬을 하는데 Apple을 무게별로 비교하여 정렬을 하라는 의미가 바로 전달이 된다. 정말 멋진일이다!
'자바' 카테고리의 다른 글
스트림을 알아보자!!! (4) | 2024.10.09 |
---|---|
동작 파라미터화와 람다의 관계성 (1) | 2024.09.30 |
알고리즘을 풀며 Comparator 인터페이스를 사용할 때 주로 클래스로 구현하거나 익명 클래스를 사용하여 정렬을 하였다.
public class AppleComparator implements Comparator<Apple> {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(o2.getWegiht());
}
}
inventory.sort(new AppleComparator());
혹은
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight()-a2.getWeight();
}
});
이런 익명클래스를 이용하였다.
하지만 자바 8부터 람다가 나오면서 경량화된 문법을 이용할 수 있다. 람다는 함수형 인터페이스를 기대하는 곳 어디에서나 사용할 수 있다. Comparator는 compare 추상 메서드를 하나 갖고 있는 함수형 인터페이스이다. Comparator를 보면 equals이나 다른 메서드가 몇개 있는 것을 볼 수 있는데 이건 디폴트 메서드이거나 정적 메서드이므로 추상 메서드는 아니다.
람다는 이러한 함수형 인터페이스의 추상메서드를 구현하는 함수라고 생각하면 된다. 그렇기 때문에 추상 메서드의 시그니처 (리턴값, 인자값등 구현에 필수적인 요소라 생각하자!)는 람다 표현식의 시그니처를 정의한다. Comparator의 함수 디스크립터(추상 메서드의 시그니처)는 (T, T) -> int이다. 이를 람다를 사용해 표현하면
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())); 로 표현할 수 있다.
컴파일러는 람다의 파라미터 형식을 추론가능하다. 그러므로 이를 또
inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight())); 로 바꿀 수 있다.
여기에서 조금 더 욕심을 부려보자. 메서드 참조를 사용하면 이를 더 직관적인 코드로 변환시킬 수 있다. 그러기 위해서는 메서드 참조가 무엇인지 알아야 한다.
메서드 참조? 메서드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어 불필요한 선언부분을 줄이는 것
예시를 통해 이해해보자. 자바 사용자라면 모두 알만한 Math.max(int a, int b) 메서드를 보자. 이를 호출하는 람다식은 (int a, int b) -> Math.max(a,b)가 될 것이다. 이를 메서드 참조로 변경하면 Math::max가 된다. a,b라는 변수가 중복되고 있기에 삭제한 후 Math.max 와 같은 호출을 Math::max로 변경하여 사용한다.
IntBinaryOperator 함수형 인터페이스는 리턴값이 int이고 int형 매개변수를 두개 받는 추상 메서드(applyAsInt)를 갖고 있다. 위에서 본 Math::max와 그렇기 때문에 함수 디스크립터가 같다.
IntBinaryOperator a = Math::max;
a.applyAsInt(100,200);
때문에 위와 같은 형태로 사용 사용할 수 있다.
이를 기반으로 기존 코드를 변경하면 inventory.sort(comparing(Apple::getWeight));로 변경할 수 있다. 정말 직관적이고 간결한 코드가 되었다. 코드만 읽어도 어떤 일을 하는 것인지 명확히 이해를 할 수 있다. 정렬을 하는데 Apple을 무게별로 비교하여 정렬을 하라는 의미가 바로 전달이 된다. 정말 멋진일이다!
'자바' 카테고리의 다른 글
스트림을 알아보자!!! (4) | 2024.10.09 |
---|---|
동작 파라미터화와 람다의 관계성 (1) | 2024.09.30 |