一、为什么引入lambda表达式
冗余的Runnable代码
-
传统写法
当需要启动一个线程去完成任务时,通常会通过 java.lang.Runnable 接口来定义任务内容,并使用
java.lang.Thread 类来启动该线程。代码如下:
public class Demo01Runnable { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("多线程任务执行!"); } }).start(); } }
-
体验lambda的更优写法
借助Java 8的全新语法,上述 Runnable 接口的匿名内部类写法可以通过更简单的lambda表达式达到等效:
public class Demo02LambdaRunnable { public static void main(String[] args) { new Thread(() -> System.out.println("多线程任务执行!")).start(); } }
lambda表达式是对匿名内部类写法的进一步简化。
二、lambda标准格式
(参数名称) -> { 代码语句 }
格式说明:
-
小括号内无参数则留空;多个参数则用逗号分隔。
- 如果小括号内有且仅有一个参数,则小括号可以省略。
-
-> 是新引入的语法格式,代表将前面的参数传递给后面的代码。
-
大括号内的语法与传统方法体要求基本一致。
- 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
使用前提:
-
使用lambda必须具有接口,且要求接口中有且仅有一个抽象方法。
无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一
时,才可以使用lambda。
-
使用lambda必须具有上下文推断。
也就是方法的参数或局部变量类型必须为lambda对应的接口类型,才能使用lambda作为该接口的实例。
lambda其实就是接口实例的简洁写法。书写lambda表达式时我们只需要关注接口中那唯一一个抽象方法的参数和返回值类型即可。
有且仅有一个抽象方法的接口,也被称为“函数式接口”。
三、练习使用lambda标准格式
1. 无参无返回
题目:
给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:
public interface Cook {
void makeFood();
}
在下面的代码中,请使用lambda的标准格式调用 invokeCook 方法,打印输出"吃饭啦!"字样:
public class Demo03InvokeCook {
public static void main(String[] args) {
// TODO 请在此使用lambda【标准格式】调用invokeCook方法
}
private static void invokeCook(Cook cook) {
cook.makeFood();
}
}
解答:
public static void main(String[] args) {
invokeCook(() ‐> System.out.println("吃饭啦!"));
}
2. 有参有返回
题目1:
假设有一个 Person 类,含有 String name 和 int age 两个成员变量,使用数组存储多个Person对象,接着对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排列。
解答:
import java.util.Arrays;
public class Demo04ComparatorLambda {
public static void main(String[] args) {
Person[] array = {
new Person("古力娜扎", 19),
new Person("迪丽热巴", 18),
new Person("马尔扎哈", 20) };
Arrays.sort(array, (a, b) ‐> a.getAge() ‐ b.getAge());
for (Person person : array) {
System.out.println(person);
}
}
}
题目2:
给定一个计算器 Calculator 接口,内含抽象方法 calc 可以将两个int数字相加得到和值:
public interface Calculator {
int calc(int a, int b);
}
在下面的代码中,请使用lambda的标准格式调用 invokeCalc 方法,完成120和130的相加计算:
public class Demo05InvokeCalc {
public static void main(String[] args) {
// TODO 请在此使用lambda【标准格式】调用invokeCalc方法来计算120+130的结果
}
private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
System.out.println("结果是:" + result);
}
}
解答:
public static void main(String[] args) {
invokeCalc(120, 130, (a, b) ‐> a + b );
}