2017-11-03 22 views
12

나는 얼마나 Comparator.comparing 함수가 작동하는지 이해하려고합니다. 나는 그것을 이해하기 위해 내 자신의 비교 방법을 만들었습니다.Java Lambda to comparator conversion - 중간 표현

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
    return (Comparator<T>) bfun; 
} 

이 함수의 마지막 행은 예외를 throw합니다. 내가

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    return (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
} 

이 기능을 변경하는 경우

그러나, 그것은 예상대로 잘 작동합니다.

람다를 Comparator으로 변환 할 수있는 두 번째 시도에서 사용하는 중간 기능 인터페이스는 무엇입니까?

+4

람다가 변환하는 형식은 표현식이 해당 컨텍스트에서 있어야하는 형식입니다. 첫 번째 예제에서 람다는 할당 된 변수 유형이므로 람다를 'BiFunction'으로 변환해야합니다. 두 번째 예제에서 람다는 메서드의 반환 유형이기 때문에 'Comparator'로 변환해야합니다. 'BiFunction'과'Comparator'는 같은 모양을 가지기 때문에 같은 람다는 문맥에 따라 달라질 수 있습니다. 그러나 서로 다른 타입을 사용하기 때문에 서로 섞는 것이 실패 할 것입니다. –

+0

나는 이것을 downvoting 해요. 품질에 대한 것이 아니라이 질문에 대한 감사가 있었기 때문에 * 3 개의 *가 실패했습니다. –

답변

11

람다를 Comparator로 변환 할 수있는 두 번째 시도가 사용하는 중간 기능적인 인터페이스는 무엇입니까?

Comparator 그 자체.

두 번째 방법에서는 Comparator으로 캐스팅 된 중간 개체가 아닌 Comparator을 정의했습니다.

이 함수의 마지막 행은 예외를 throw합니다.

예. 그렇습니다.

두 클래스가 기능 인터페이스이고 동일한 서명과 동일한 반환 유형을 가진 유사한 메서드를 사용하는 경우 해당 클래스를 서로 바꾸어 사용할 수 있다는 의미는 아닙니다.

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    final BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
    return bfun::apply; // (a, b) -> bfun.apply(a, b); 
} 
5

두 번째 시도에서 중간 기능 인터페이스는 단순히 Comparator<T>입니다 :

당신 -


재미있는 트릭은 당신이 BiFunction<T, T, Integer> bfun의 방법 apply를 참조하여 Comparator<T>을 할 수 코드 스 니펫이 다음과 같기 때문에이를 볼 수 있습니다.

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    Comparator<T> comparator = (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
    return comparator; 
}