Java lambda表达式-如何省略接口名称?

Java lambda表达式-如何省略接口名称?,java,Java,我正在阅读有关lambda表达式的oracle教程: 要指定搜索条件,请实现CheckPerson 接口: 然后使用它 printPersons( roster, new CheckPerson() { public boolean test(Person p) { return p.getGender() == Person.Sex.MALE && p.getAge() >= 18

我正在阅读有关lambda表达式的oracle教程:

要指定搜索条件,请实现CheckPerson 接口:

然后使用它

printPersons(
    roster,
    new CheckPerson() {
        public boolean test(Person p) {
            return p.getGender() == Person.Sex.MALE
                && p.getAge() >= 18
                && p.getAge() <= 25;
        }
    }
);
printperson(
名册
新支票人(){
公共布尔测试(p人){
返回p.getGender()==Person.Sex.MALE
&&p.getAge()>=18
&&p.getAge()p.getGender()==Person.Sex.MALE
&&p.getAge()>=18
&&p.getAge()它在Java中称为SAM(单一抽象方法)类型,是的,接口仍然在使用

让我们看一下
印刷人的签名

public static void printPersons(List<Person> roster, CheckPerson tester)
publicstaticvoidprintperson(列表花名册、检查人员测试员)
所以,Java编译器知道,如果您为它提供一个lambda,那么这个lambda应该符合
CheckPerson
提供的单个方法

我们是否在lambda中使用CheckPerson接口

我们不使用它,我们定义它。我们给它一个实现。我们通过编写lambda表达式来实现那个接口

“in lambda”是您的误解,因为lambda是该接口的一个实例

他们说他们省略了这个方法,我在lambda中没有看到任何测试-这很清楚。但他们也删除了接口CheckPerson的名称


这不是关于“放弃”或“忽略”有些东西。它是关于用另一个语法结构替换一个语法结构。你用lambda表达式替换一个匿名类,使你的代码更具表现力,更不冗长。

出于所有目的和目的,lambda表达式是简化匿名类编写方式的语法糖

这并不完全正确,因为编译器实际上并没有生成匿名类(尽管它可能会生成),关键字
this
之类的东西会改变其含义,但在其他方面它确实非常相似

因此,使用匿名类的代码是:

new CheckPerson() {
    public boolean test(Person p) {
        return p.getGender() == Person.Sex.MALE
            && p.getAge() >= 18
            && p.getAge() <= 25;
    }
}
你会得到:

(Person p) -> {
其中,
->
是lambda表达式语法,告诉编译器推断其余部分

到目前为止,我们已经减少了:

new CheckPerson() {
    public boolean test(Person p) {
        return p.getGender() == Person.Sex.MALE
            && p.getAge() >= 18
            && p.getAge() <= 25;
    }
}

这就是简写的lambda表达式(语法糖)用于执行与原始匿名类相同的操作。

检查
printperson
方法的签名。其第二个参数为
CheckPerson
类型。无需指定它,因此在lamda表达式中省略了它。谢谢,我错过了它的调用而不是声明。Lambda本身并不是一个严格意义上的实例,因为它不能引用引用它自己的标识。你不能从lambda body调用它的
默认
方法,就像你用匿名类实现同一个body一样。@M.Prokhorov,“lambda本身并不是一个实例,因为它不能引用自己的标识”-这很有趣。你能提供一个链接让我可以阅读更多细节吗?@AlexeiMartianov实际上,这是一个声明。调用将在方法
printPersons
@AlexeiMartianov方法printPersons的“以下调用”,而不是你传递的lambda
new CheckPerson() {
    public boolean test(Person p) {
(Person p) -> {
new CheckPerson() {
    public boolean test(Person p) {
        return p.getGender() == Person.Sex.MALE
            && p.getAge() >= 18
            && p.getAge() <= 25;
    }
}
(Person p) -> {
    return p.getGender() == Person.Sex.MALE
        && p.getAge() >= 18
        && p.getAge() <= 25;
}
p -> p.getGender() == Person.Sex.MALE
  && p.getAge() >= 18
  && p.getAge() <= 25