2017-11-03 25 views
12

Tôi đang cố gắng hiểu ý nghĩa của cách hoạt động của hàm Comparator.comparing. Tôi đã tạo phương pháp so sánh của riêng mình để hiểu nó.Java Lambda để so sánh chuyển đổi - trình bày trung gian

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; 
} 

Dòng cuối cùng trong chức năng này sẽ ném ngoại lệ.

Tuy nhiên, nếu tôi thay đổi chức năng này để

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)); 
} 

Nó hoạt động tốt như mong đợi.

Giao diện chức năng trung gian mà lần thử thứ hai sử dụng, có thể chuyển đổi lambda thành Comparator là gì?

+4

Loại lambda chuyển thành là loại biểu thức phải từ ngữ cảnh của nó. Trong ví dụ đầu tiên lambda phải chuyển đổi thành 'BiFunction' vì đó là kiểu biến mà nó gán cho nó. Trong ví dụ thứ hai, lambda phải chuyển đổi thành một 'Comparator' vì đó là kiểu trả về của phương thức. 'BiFunction' và' Comparator' có cùng một "hình dạng", do đó, lambda giống nhau có thể trở thành tùy thuộc vào ngữ cảnh, nhưng chúng là các kiểu khác nhau để đúc một cái khác sẽ thất bại. –

+0

Tôi đang downvoting cái này. Không phải vì chất lượng, nhưng vì có một số kiểm toán về câu hỏi này, trong đó * ba * không thành công. –

Trả lời

11

Giao diện chức năng trung gian mà lần thử thứ hai sử dụng, có thể chuyển đổi lambda thành Comparator là gì?

Bản thân số Comparator.

Trong phương pháp thứ hai, bạn đã xác định Comparator, không phải là đối tượng trung gian đã được truyền tới số Comparator.

Dòng cuối cùng trong hàm này sẽ ném ngoại lệ.

Có, nên.

Nếu hai lớp là giao diện chức năng và có các phương thức tương tự (với chữ ký giống hệt nhau và cùng loại trả về), điều đó không có nghĩa là chúng có thể được sử dụng thay thế lẫn nhau.


Một mẹo thú vị - bạn có thể làm cho một Comparator<T> bằng cách tham khảo phương pháp 's BiFunction<T, T, Integer> bfunapply:

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

Giao diện chức năng trung gian trong nỗ lực thứ hai của bạn chỉ đơn giản là Comparator<T> là:

Bạn có thể thấy điều này vì đoạn mã của bạn tương đương như sau:

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; 
} 
Các vấn đề liên quan