引用参考文档链接
模型
1 | LambdaParameters -> LambdaBody |
参数
无入参案例
JDK7匿名内部类版本:
1 | new Thread(new Runnable() { |
JDK8 Lambda版本:
1 | new Thread(() -> System.out.println("起飞")).start(); |
一个入参案例
自定义接口类
1 | public interface LambdaSingleParam { |
自定义调用类
1 | public class LambdaFuncAccepter { |
JDK7 匿名类版本
1 | LambdaFuncAccepter.testFunc(new LambdaSingleParam() { |
JDK8 Lambda版本
1 | LambdaFuncAccepter.testFunc((LambdaSingleParam) System.out::println); |
多入参案例
自定义接口类
1 | public interface LambdaMultipleParams { |
自定义调用类
1 | public class LambdaFuncAccepter { |
JDK7 匿名类版本
1 | LambdaFuncAccepter.testFunc(new LambdaMultipleParams() { |
JDK8 Lambda版本
1 | LambdaFuncAccepter.testFunc((a, b) -> System.out.println(a + b)); |
方法体
单条执行语句
无return案例
有return案例
1 | public interface LambdaWIthReturnNoParam { |
多条执行语句
无return案例
1 | // 使用runable接口 |
有return案例
1 | // 使用 LambdaWIthReturnNoParam 接口 |
注意事项
- lambda表达式的使用必须要有对应的函数接口,并且该接口有且仅有一个无默认实现的函数(当接口的其他函数均由默认实现时,该接口也可使用lambda,如
Comparator
)1
2
3
4Integer[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Arrays.sort(a, (o1, o2) -> o2 - o1);
// 也可写成,不过Integer内置是固定升序的,无法修改
Arrays.sort(a, Integer::compare); - 多参数场景下,要么都声明入参类型,要么都不声明,不允许一部分声明,一部分隐藏
1
2LambdaFuncAccepter.testFunc((a, int b) -> System.out.println(a + b));
// 此时编译器会报错 - final 不能修饰推断类型入参,如需使用final,需要将入参显示设置类型
1
2
3
4// 编译器会提示异常
LambdaFuncAccepter.testFunc((a, final b) -> System.out.println(a + b));
// 需调整为如下所示:
LambdaFuncAccepter.testFunc((int a, final int b) -> System.out.println(a + b)); - lambda方法体使用外部变量时,必须遵守声明时赋值后续不可赋值规则(同final修饰规则),但调用对象函数修改对象内部状态合法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16StringBuilder sb = new StringBuilder();
new Thread(() -> {
// Variable used in lambda expression should be final or effectively final
// 虽然sb没有被final声明,但是在lambda内部存在隐形的final限制
// sb = new StringBuilder();
sb.append(111);
System.out.println("line1");
}).start();
int y = 1;
// 即便是在外部在初始化后再修改赋值,此时已经破坏final规则
y = 3;
new Thread(() -> {
// Variable used in lambda expression should be final or effectively final
System.out.println(y);
}).start(); - 使用数组一类时,需要注意下标的使用,如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15int[] b = {1, 2, 3};
for (int i = 0; i < b.length; i++) {
new Thread(() -> {
// Variable used in lambda expression should be final or effectively final
// 此时 i 不是遵守final规则的变量
System.out.println(b[i]);
}).start();
}
// 可以修改调整如下所示:
for (int i : b) {
new Thread(() -> {
// 此时变量i作为临时变量还尚未经历再一次的赋值修改,因此还遵守 effectively final 规则
System.out.println(i);
}).start();
} - lambda方法体使用外部变量时,必须确保所有外部变量均以完成初始化(仅声明不行,如分支,必须确保变量初始化)
1
2
3
4
5
6
7
8int x;
if (sb.length() > 5) {
x = 1;
}
new Thread(() -> {
// Variable 'x' might not have been initialized
System.out.println(x);
}).start();