Java Lambda到比较器的转换-中间表示
我试图弄清楚比较器是如何工作的。我创建了自己的比较方法来理解它Java Lambda到比较器的转换-中间表示,java,lambda,java-8,comparator,functional-interface,Java,Lambda,Java 8,Comparator,Functional Interface,我试图弄清楚比较器是如何工作的。我创建了自己的比较方法来理解它 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 (Comp
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;
}
专用静态比较器比较(函数f){
双函数bfun=(ta,tb)->f.apply(a).compareTo(f.apply(b));
返回(比较器)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));
}
专用静态比较器比较(函数f){
返回(ta,tb)->f.apply(a)。与(f.apply(b)比较;
}
它和预期的一样好
第二次尝试使用的中间功能接口是什么,它能够将lambda转换为比较器
第二次尝试使用的中间功能接口是什么,能够将lambda转换为比较器
比较器本身
在第二种方法中,您定义了一个比较器
,而不是一个已转换到比较器
的中间对象
此函数的最后一行引发异常
是的,应该是这样
如果两个类是函数接口,并且具有类似的方法(具有相同的签名和相同的返回类型),这并不意味着它们可以互换使用
一个有趣的技巧-您可以通过参考双功能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);
}
专用静态比较器比较(函数f){
最终的双函数bfun=(ta,tb)->f.apply(a).比较(f.apply(b));
返回bfun::apply;//(a,b)->bfun.apply(a,b);
}
第二次尝试中的中间功能接口只是比较器
:
您可以看到这一点,因为您的代码片段相当于以下内容:
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;
}
专用静态比较器比较(函数f){
比较器比较器=(ta,tb)->f.apply(a).compareTo(f.apply(b));
返回比较器;
}
lambda转换为的类型是表达式必须来自其上下文的类型。在第一个示例中,lambda必须转换为双函数
,因为这是分配给它的变量的类型。在第二个示例中,lambda必须转换为比较器
,因为这是方法的返回类型BiFunction
和Comparator
具有相同的“形状”,因此相同的lambda可以根据上下文变为两种类型,但它们是不同的类型,因此将一种类型转换为另一种类型将失败。我对此投了反对票。不是为了质量,而是因为有很多关于这个问题的审计,其中有三个没有通过。