为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕桂英3389331 2023-06-21 15:39:55
要指定搜索条件,您可以实现 CheckPerson 接口:interface CheckPerson {     boolean test(Person p); }然后使用它printPersons(    roster,    new CheckPerson() {        public boolean test(Person p) {            return p.getGender() == Person.Sex.MALE                && p.getAge() >= 18                && p.getAge() <= 25;        }    });然后CheckPerson 接口是一个函数式接口。函数式接口是指仅包含一个抽象方法的任何接口。(一个函数式接口可能包含一个或多个默认方法或静态方法。)因为一个函数式接口只包含一个抽象方法,所以在实现它时可以省略该方法的名称。为此,您不使用匿名类表达式,而是使用 lambda 表达式,它在以下方法调用中突出显示:printPersons(    roster,    (Person p) -> p.getGender() == Person.Sex.MALE        && p.getAge() >= 18        && p.getAge() <= 25);他们说他们省略了该方法,我在 lambda 中没有看到test- 这很清楚。但他们也删除了界面名称CheckPerson。为什么解释中没有提到呢?我们是否使用CheckPersonlambda 中的接口?
查看完整描述

3 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

我们是否使用 lambda 中的 CheckPerson 接口?

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

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

他们说他们省略了方法,我在 lambda 中看不到任何测试——这很清楚。但他们也放弃了接口 CheckPerson 的名称。

这不是关于“丢弃”或“省略”某些东西。它是关于用另一种语法结构替换一种语法结构。您将匿名类替换为 lambda 表达式,以使您的代码更具表现力且更简洁。


查看完整回答
反对 回复 2023-06-21
?
函数式编程

TA贡献1807条经验 获得超9个赞

它在 Java 中称为 SAM(单一抽象方法)类型,是的,仍然使用接口。

让我们看一下 的签名printPersons

public static void printPersons(List<Person> roster, CheckPerson tester)

因此,Java 编译器知道,如果您为其提供 lambda,则该 lambda 应该遵守CheckPerson提供的单个方法。


查看完整回答
反对 回复 2023-06-21
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

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


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


所以,使用匿名类的代码是:


new CheckPerson() {

    public boolean test(Person p) {

        return p.getGender() == Person.Sex.MALE

            && p.getAge() >= 18

            && p.getAge() <= 25;

    }

}

现在,由于编译器知道 的第二个参数printPersons必须是一个CheckPerson对象,它可以在看到 lambda 表达式时推断出这一点。由于接口只有一个方法,它也可以推断出你需要实现这样一个方法。


但是,您仍然必须列出参数,这意味着如果您删除可以从前两行推断出的所有内容:


new CheckPerson() {

    public boolean test(Person p) {

你得到:


(Person p) -> {

其中->是告诉编译器推断其余部分的 lambda 表达式语法。


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


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;

}

现在我们应用更多的语法糖,即让编译器做更多的工作,以删除“模板”的东西。


参数类型可以推断出来,所以不需要给出。


如果只有一个参数,则不需要()括号。


如果方法中唯一的语句是return语句,则删除{}大括号、return关键字和;分号,只留下普通表达式。


结果:


p -> p.getGender() == Person.Sex.MALE

  && p.getAge() >= 18

  && p.getAge() <= 25

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


查看完整回答
反对 回复 2023-06-21
  • 3 回答
  • 0 关注
  • 123 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信