为什么 lambda 表达式可以用作比较器?

2023-11-27

在书里OCP学习指南有一个关于比较器的示例,可以通过两种方式初始化。第一个是通过像这样的匿名类:

Comparator<Duck> byWeight = new Comparator<Duck>(){
    public int compare(Duck d1, Duck d2){
        return d1.getWeight() - d2.getWeight();
    }
};

这个我能理解。根据这本书,这可以用如下的 lambda 表达式替换:

Comparator<Duck> byWeight = (d1,d2) -> d1.getWeight() - d2.getWeight();

现在这个我不明白了。 lambda 表达式不返回 Comparator 对象,现在我想到它不能返回 Comparator 对象,因为 Comparator 是一个接口。

也是如此new第一个示例中的运算符引用了正在创建的名为 Comparator 的匿名类,因为该匿名类实现了 Comparator 接口?

那么示例 2 中究竟发生了什么?是否以某种方式从 lambda 表达式创建了一个对象?在此示例中,您使用byWeight作为参考变量对吗?

我真的不明白这个,有人可以解释一下吗?谢谢。


如果您阅读了的文档Comparator界面, 你可以阅读:

功能接口:这是一个功能接口因此可以用作 lambda 表达式或方法引用的赋值目标。

The Comparator<T>接口是这样的实施方式类似于:

@FunctionalInterface
public interface Comparator<T> {

    int compare(T o1, T o2);

    // ...

}

现在如果我们看一下文档@FunctionalInterface we see:

用于指示接口类型的信息注释类型 声明是旨在成为一个功能性接口定义为 Java 语言规范。从概念上讲,一个功能接口有 恰好是一种抽象方法。由于默认方法有一个 实现,它们不是抽象的。如果一个接口声明了一个 抽象方法重写的公共方法之一java.lang.Object,这也不计入接口的 抽象方法计数,因为接口的任何实现都会 有一个实现java.lang.Object或其他地方。

所以基本上如果你有一个接口one抽象方法,并将接口注释为@FunctionalInterface,那么该接口就是函数的目标:因为您或多或少构造了一个实现函数接口的匿名类,并且您指定的函数是唯一抽象方法的实现。

换句话说,表达式:

Comparator<Duck> byWeight = <somelambda>

is 相等的 to:

Comparator<Duck> byWeight = new Comparator<Duck>(){
    public int compare(Duck d1, Duck d2){
        return <somelambda>(d1,d2);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 lambda 表达式可以用作比较器? 的相关文章

随机推荐