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

时间:2017-11-03 16:11:31

标签: java lambda java-8 comparator 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;
}

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

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

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

按预期工作正常。

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

2 个答案:

答案 0 :(得分:11)

  

第二次尝试使用的中间功能接口是什么,能够将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);
}

答案 1 :(得分:5)

第二次尝试中的中间功能界面只是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;
}