Java中的lambda(λ)表达式
Lambda
表达式是JDK1.8
推出的一种新特性,是一个匿名函数
,是对匿名函数的简写形式,我们可以把Lambda
表达式理解为是一段可以传递的代码(将代码像数据一样进行传递),可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。Lambda
表达式就是对函数式接口
的一种简写形式,所以只有函数式接口,我们才能用Lambda
表达式;换句话说,Lambda
表达式需要函数式接口的支持。- 综上,
Lambda
表达式就是用来简化创建函数式接口对象的。
一、函数式接口(FunctionalInterface)
1.函数式接口的定义
- 函数式接口是只有一个抽象方法(不包含Object中的方法)的接口。
@FunctionalInterface
注解,写在接口声明上面,如果不报错,就是函数式接口。/** * 只有一个抽象方法,是函数式接口 */ @java.lang.FunctionalInterface interface FunctionalInterface { int add(int x, int y); } /** * 有两个抽象方法,不是函数式接口 */ //@java.lang.FunctionalInterface interface NonFunctionalInterface { int mul(int x, int y); int div(int x, int y); } /** * 有一个抽象方法和一个默认方法,是函数式接口 */ @java.lang.FunctionalInterface interface DefaultFunctionalInterface { int mul(int x, int y); default int sub(int x, int y){ return x - y; } }
2.Java中四大函数式接口
JDK1.8
之后java.util.function
包下,提供了很多函数式接口,作为参数传递。
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer<T>【消费型接口】 | T | void | 对类型为 T 的对象应用操作,包含方法:void accept(T t) |
Supplier<T>【供给型接口】 | 无 | T | 返回类型为 T 的对象,包含方法:T get() |
Function<T, R>【函数型接口】 | T | R | 对类型为 T 的对象应用操作,并返回结果。结果是 R 类型的对象。包含方法:R apply(T t) |
Predicate<T>【断言型接口】 | T | boolean | 确定类型为 T 的对象是否满足某约束,并返回 Boolean 值。包含方法 boolean test(T t) |
二、Lambda表达式语法
1.基础语法
Lambda
表达式的核心就是实现的这个接口中的抽象方法中的形参列表 -> 抽象方法的处理
,因此根据形参列表与返回值的不同,Lambda
表达式的具体写法也不相同。lambda
表达式的基本语法格式://1、基本格式,根据参数列表和返回值的不同有不同的写法。 (parameters) -> {statements;} (parameters) -> expression
- ① 可以省略方法名,IDEA会帮你自动检测方法名。
- ② 可以省略方法中的形参类型。
- ③ 如果只有一个参数,可以省略小括号;如果没有参数,不能省略小括号。
- ④ 如果对抽象方法的实现逻辑只有一行,可以省略方法体的大括号,当然如果不止一行,就不能省略。
- ⑤ 如果抽象方法有返回值且实现逻辑只有一行,不能直接去掉大括号,还需要去掉 return 关键字。
- ⑥ Lambda 表达式也可以作为参数传递。
2.方法引用
- 方法引用其实是Lambda表达式的另一种写法,当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。
- 注意:实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!
- 方法引用:使用操作符
::
将方法名和对象或类的名字分隔开来,三种主要的情况为:对象::实例方法
//使用基本的Lambda表达式的语法 Consumer<String> consumer = x -> System.out.println(x); //使用方法引用的方式 Consumer<String> consumer = System.out::println; //输出结果为 GDB consumer.test("GDB");
类::静态方法
//使用基本的Lambda表达式的语法 Function<Double, Double> function = x -> Math.sqrt(x); //使用方法引用的方式 Function<Double, Double> function = Math::sqrt; //输出结果为 4.0 System.out.println(function.apply(16.0));
类::实例方法
//使用基本的lambda表达式的语法 Predicate<String> predicate = x -> x.isEmpty(); //使用方法引用的方式 Predicate<String> predicate = String::isEmpty; //输出结果为false System.out.println(predicate.test("123"));
三、Lambda表达式作用
1.替代匿名内部类
- 毫无疑问,Lambda表达式用得最多的场合就是替代匿名内部类,而实现
Runable
接口是匿名内部类的经典例子。lambda表达式的功能相当强大,用() -> {}
就可以代替整个匿名内部类!public void oldRunnable() { //使用匿名内部类的方式 new Thread(new Runnable() { @Override public void run() { System.out.println("The old runnable now is using!"); } }).start(); } public void newRunnable() { //使用lambda表达式的方式 new Thread(() -> System.out.println("The new Runnable now is using!")).start(); }
2.使用Lambda表达式对集合进行迭代
- Java的集合类是日常开发中经常用到的,甚至说没有哪个Java代码中没有使用到集合类的。而对集合类最常见的操作就是进行迭代遍历了。
public class Lambda { public static void main(String[] args) { List<String> languages = Arrays.asList("java", "python", "C", "C++", "C#", "Go", "R", "JavaScript"); //Java8以前使用加强 For for (String var : languages) { System.out.println(var); } System.out.println("==========================================="); //使用 Lambda 表达式 languages.forEach(System.out::println); } }
3.Stream操作
Stream
就是Java8
提供给我们的对于集合元素统一、快速、并行操作的一种方式。它能充分应用多核的优势,以及配合Lambda
表达式、链式结构对集合等进行许多有用的操作。
四、参考
[1]. 什么是Lambda表达式,它有什么作用?
[2]. 详解Java中的Lambda表达式