Java Lambda到比较器转换 - 中间表示

pat*_*fox 13 java lambda comparator java-8 functional-interface

我试图理解Comparator.comparing函数是如何工作的.我创建了自己的比较方法来理解它.

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;
}
Run Code Online (Sandbox Code Playgroud)

此函数的最后一行抛出异常.

但是,如果我将此功能更改为

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));
}
Run Code Online (Sandbox Code Playgroud)

它按预期工作得很好.

第二次尝试使用的中间功能接口是什么,能够将lambda转换为Comparator

And*_*lko 12

第二次尝试使用的中间功能接口是什么,能够将lambda转换为Comparator?

Comparator本身.

在第二种方法中,您已经定义了一个Comparator,而不是已经转换为的中间对象Comparator.

此函数的最后一行抛出异常.

是的,它应该.

如果两个类是功能接口并且具有相似的方法(具有相同的签名和相同的返回类型),则并不意味着它们可以互换使用.


一个有趣的技巧 - 您可以Comparator<T>通过参考BiFunction<T, T, Integer> bfun方法来制作apply:

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);
}
Run Code Online (Sandbox Code Playgroud)


Tho*_*sch 6

第二次尝试的中间功能界面就是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;
}
Run Code Online (Sandbox Code Playgroud)