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

要指定搜索条件,您可以实现 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 中的接口?

慕桂英3389331
浏览 131回答 3
3回答

倚天杖

我们是否使用 lambda 中的 CheckPerson 接口?我们不使用它,我们定义它。我们给它一个实现。我们通过编写 lambda 表达式来实现该接口。“in lambda”是你的误解,因为 lambda是该接口的一个实例。他们说他们省略了方法,我在 lambda 中看不到任何测试——这很清楚。但他们也放弃了接口 CheckPerson 的名称。这不是关于“丢弃”或“省略”某些东西。它是关于用另一种语法结构替换一种语法结构。您将匿名类替换为 lambda 表达式,以使您的代码更具表现力且更简洁。

函数式编程

它在 Java 中称为 SAM(单一抽象方法)类型,是的,仍然使用接口。让我们看一下 的签名printPersons:public&nbsp;static&nbsp;void&nbsp;printPersons(List<Person>&nbsp;roster,&nbsp;CheckPerson&nbsp;tester)因此,Java 编译器知道,如果您为其提供 lambda,则该 lambda 应该遵守CheckPerson提供的单个方法。

摇曳的蔷薇

出于所有意图和目的,lambda 表达式是一种语法糖,用于简化编写匿名类的方式。这并不完全正确,因为编译器实际上并没有生成匿名类(尽管它可以生成),并且关键字之类的东西会this改变含义,但在其他方面它确实非常相似。所以,使用匿名类的代码是:new CheckPerson() {&nbsp; &nbsp; public boolean test(Person p) {&nbsp; &nbsp; &nbsp; &nbsp; return p.getGender() == Person.Sex.MALE&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && p.getAge() >= 18&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && p.getAge() <= 25;&nbsp; &nbsp; }}现在,由于编译器知道 的第二个参数printPersons必须是一个CheckPerson对象,它可以在看到 lambda 表达式时推断出这一点。由于接口只有一个方法,它也可以推断出你需要实现这样一个方法。但是,您仍然必须列出参数,这意味着如果您删除可以从前两行推断出的所有内容:new CheckPerson() {&nbsp; &nbsp; public boolean test(Person p) {你得到:(Person p) -> {其中->是告诉编译器推断其余部分的 lambda 表达式语法。到目前为止,我们已经减少了:new CheckPerson() {&nbsp; &nbsp; public boolean test(Person p) {&nbsp; &nbsp; &nbsp; &nbsp; return p.getGender() == Person.Sex.MALE&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && p.getAge() >= 18&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && p.getAge() <= 25;&nbsp; &nbsp; }}到:(Person p) -> {&nbsp; &nbsp; return p.getGender() == Person.Sex.MALE&nbsp; &nbsp; &nbsp; &nbsp; && p.getAge() >= 18&nbsp; &nbsp; &nbsp; &nbsp; && p.getAge() <= 25;}现在我们应用更多的语法糖,即让编译器做更多的工作,以删除“模板”的东西。参数类型可以推断出来,所以不需要给出。如果只有一个参数,则不需要()括号。如果方法中唯一的语句是return语句,则删除{}大括号、return关键字和;分号,只留下普通表达式。结果:p -> p.getGender() == Person.Sex.MALE&nbsp; && p.getAge() >= 18&nbsp; && p.getAge() <= 25这是简写 lambda 表达式(语法糖),用于执行与原始匿名类相同的操作。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java