Java 中的 Lambda 表达式

Lambda 表达式的意义

Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待。使其独立存在,你可以将其赋值给一个变量,或将他们当做参数传给其他函数。不过,在 Java 中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface)。

Lambda 表达式特征

Lambda 表达式没有声明的方法,也即没有访问修饰符、返回值声明以及名字。

Lambda 表达式的结构

  • 一个 Lambda 表达式可以有零个或多个参数
  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)(a) 效果相同
  • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b)(int a, int b)(String a, int b, float c)
  • 空圆括号代表参数集为空。例如:() -> 42
  • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
  • Lambda 表达式的主体可包含零条或多条语句
  • 如果 Lambda 表达式的主体只有一条语句,花括号 {} 可省略,return关键字也可以省略,匿名函数的返回类型与该主体表达式一致
  • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号 {} 中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

Lambda 表达式举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 1. 不需要参数, 返回值为 5
() -> 5

// 2. 接收一个参数(数字类型), 返回其 2 倍的值
x -> 2 * x

// 3. 接受 2 个参数(数字), 并返回他们的差值
(x, y) -> x – y

// 4. 接收 2 个 int 型整数, 返回他们的和
(int x, int y) -> x + y

// 5. 接受一个 string 对象, 并在控制台打印, 不返回任何值(看起来像是返回 void)
(String s) -> System.out.print(s)

Lambada 表达式的作用域

访问局部变量

  • 可以直接在 lambda 表达式中访问外层中的 final 局部变量
  • lambda 表达式中访问的外层局部变量时必须不可被后面的代码修改(即隐性的具有 final 的语义),Lambda 表达式中也不能修改
  • 在 Lambda 表达式当中被引用的变量的值不可以被更改。
  • 在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

访问对象字段与静态变量

  • 和局部变量不同的是,Lambda 内部对于实例的字段(即:成员变量)以及静态变量是即可读又可写。
  • 不能访问接口的默认方法

Lambda 表达式中的 this

  • Lambda 表达式中使用 this 会引用创建该 Lambda 表达式的方法的 this 参数。