学习内容
Lambda表达式
在一个 Runnable 接口中,只有一个 run() 方法:
public abstract void run();
代码特点:
无参数:不需要任何条件即可执行该方案。
无返回值:该方案不产生任何结果。
代码块(方法体):该方案的具体执行步骤。
同样的语义体现在 Lambda 语法中,要更加简单:
() ‐> System.out.println("多线程任务执行!")
前面的一对小括号即 run 方法的参数(无),代表不需要任何条件;
中间的一个箭头代表将前面的参数传递给后面的代码;
后面的输出语句即业务逻辑代码。
Lambda标准格式
Lambda省去面向对象的条条框框,格式由3个部分组成:
一些参数
一个箭头
一段代码
即:(参数类型 参数) -> {代码}
格式说明
小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
-> 是新引入的语法格式,代表指向动作。
大括号内的语法与传统方法体要求基本一致。
省略规则
在Lambda标准格式的基础上,使用省略写法的规则为:
小括号内参数的类型可以省略;
如果小括号内有且仅有一个参,则小括号可以省略;
如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
凡是可以通过上下文推导出来的内容,都可以省略书写。
可省略的内容:
参数列表:括号中参数的数据类型可省略
参数列表:括号中如果只有一个参数,那么类型和 () 都可以省略。
代码块:如果代码块 {} 中的代码只有一行,那么无论是否有返回值,都可以省略({},return,分号),但他们3个必须一起省略
使用前提
使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。无论是内置接口还是自定义接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda。
使用Lambda必须具有上下文推断,也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
函数式接口
预定义的函数式接口
工作内容
任务1
尝试自定义几个函数式接口用于之前任务的代码中,并用 Lambda 表达式改造之前的代码。
答:在之前写过的 4 线程用同一个锁的任务基础上修改。
以单个线程为例:
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized ("lock1") {
System.out.println("t1 线程开始");
try {
"锁".wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 线程结束");
}
}
});
线程 t1 中,在 Runnable 中有且仅有一个抽象方法:run(),因此满足Lambda
表达式的省略条件。
因此可以改写成:
new Thread(() -> {
System.out.println("t1线程开始");
try {
"lock1".wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 线程结束");
}).start();
总结
个人体会,Lambda 表达式是很容易眼高手低的知识点。看文档、看别人代码的时候会觉得比较好理解,实际自己写的时候却很容易卡壳,感觉明天还需要自己再把别人的代码多敲几次,在敲的过程中也可以更好的体会 Lambda 的省略原则。