跳转到内容

Java 编程/Lambda 表达式

来自维基教科书,开放的书籍,开放的世界

Lambda 表达式是在 Java 8 中引入的,作为一种简洁的方式来描述功能,作为语言中的一级成员。虽然原理类似于使用匿名内部类来满足接口,但 lambda 表达式使代码更易读。

即,而不是

Collection<Book> results = library.findAll(new Predicate() {
   @Override
   public boolean test(Book book) {
       return book.getTitle().contains("Java");
   }
});

我们可以简单地说

Collection<Book> results = library.findAll(book -> book.getTitle().contains("Java"));

Lambda 表达式由两个部分组成,这两个部分由 -> 字符(称为“箭头”)隔开。

Parameters -> Body

参数定义表达式的输入。通常,参数是由括号括起来的、由逗号分隔的类型和标识符列表。

( Type1 identifier1 , Type2 identifier2 ) -> Body

但是,类型通常可以从上下文推断出来,可以省略。

( identifier1, identifier2 ) -> Body

并且,如果只有一个输入且其类型可以推断出来,则可以省略括号。

identifier1 -> Body

Lambda 表达式的主体描述了应该对这些输入(如果有)执行的操作。通常,主体就像任何其他块一样。

Parameters -> {
    statements;
    ...
    return statement;
}

对于只对输入进行操作的表达式,可以省略 return 语句。

Parameters -> {
    statements;
    ...
}

如果主体只包含一条语句,则可以省略花括号和结尾分号。

Parameters -> statement

如果表达式包含单个 return 语句,则可以省略花括号、return 关键字和结尾分号。

Parameters -> result

java.util.function 命名空间包含许多现成的结构,介绍了一些标准术语,这些术语属于 3 种主要类型。

  1. “函数”:从数学意义上讲的真实函数,正好接收一个输入并提供一个输出;
  2. “消费者”:接受输入但不提供任何输出(按传统意义)的实体;以及
  3. “供应商”:每次被调用时都会提供一个值,而无需任何输入的实体。
接口 输入 结果 签名
Function<T, R> T R T -> R 接受类型为 T 的一个输入并返回类型为 R 的东西。
Consumer<T> T T -> 接受类型为 T 的一个输入,不返回任何东西(void)。
Supplier<R> R -> R 不接受任何输入,并返回类型为 R 的对象。

Function 和 Consumer 也具有接受两个输入的“Bi”变体。

接口 输入 结果 签名
BiFunction<S, T, R> S, T R (S, T) -> R 接受两个输入,一个类型为 S,另一个类型为 T,并返回类型为 R 的东西。
BiConsumer<S, T> S, T (S, T) -> 接受两个输入,一个类型为 S,另一个类型为 T,不返回任何东西(void)。

进一步阅读

[编辑 | 编辑源代码]
  • 流/集合
  • 函数式接口
  • 方法引用
华夏公益教科书