lambda 表达式
Lambda 是一个匿名函数,使用它可以写出更简洁、更灵活的代码。Lambda 表达式的本质:函数式接口的实现。
在 Java 8 中引入了新的操作符 ->
,称为 lambda 操作符或者箭头操作符。将 lambda 分为两个部分:
- 左侧:指定了 Lambda 表达式需要的参数列表。
- 右侧:指定了 Lambda 体,是抽象方法的实现逻辑。
lambda 表达式中参数数据类型可以省略,因为可由编译器推断得出,称为类型推断。
应用举例:
lambda 表达式可以从匿名类转换为 lambda 表达式。
匿名类:
1 | Runnable r = new Runnable() { |
lambda 表达式:
1 | Runnable r = () -> System.out.println("hello world"); |
函数式接口
只包含一个抽象方法的接口,称为函数式接口。可以通过 Lambda 表达式来创建该接口的对象。
可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
在 Java 中,Lambda 表达式是对象,而不是函数。Lambda 表达式就是一个函数式接口的实例。
作为参数
Lambda 表达式可以作为参数传递,为了将 Lambda 表达式作为参数传递,接收 Lambda 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型。如:
定义函数式接口:
1 |
|
定义函数:
1 | public String f(MyFunc<String> mf, String s) { |
Lambda 表达式作为函数参数:
1 | String ret = f(str -> str.toUpperCase(), "abcde") |
内置函数型接口
在 java.util.function 包下定义了丰富的函数式接口。
四大核心函数式接口:
其他接口:
方法引用构造器引用
方法引用
Lambda 表达式中的操作已经有实现的方法了,就可以使用方法引用。方法引用就是 Lambda 表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法。格式:使用操作符 ::
将类(对象)与方法名字分隔。
要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致。
有三种使用情景:
- 对象::实例方法名。
- 类::静态方法名。
- 类::实例方法名(this 看作是第一个参数)。
如:
1 | Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y); |
构造器引用
也可以使用构造器引用,把构造器引用赋值给函数型接口。格式:ClassName::new
要求:构造器参数列表要与接口中抽象方法的参数列表一致,且方法的返回值即为构造器对应类的对象。
如:
1 | Function<Integer, MyClass> fun1 = (n) -> new MyClass(n); |
数组构造器引用:
1 | Function<Integer, Integer[]> fun1 = (n) -> new Integer[n]; |