Lambda表达式
- Lambda表达式
1. Lambda的引入
// 开启一条新线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("开启了一条新线程!~");
}
}).start();
上面代码的缺点
- Thread的构造方法中, 必须传入Runnable接口的实现类对象, 我们就不得不创建一个类, 实现Runnable接口;
- 如果为了省去创建一个类的麻烦, 我们不得不使用匿名内部类;
- 不得不使用匿名内部类, 我们有不得不重写run()方法
- 重写run()方法, 不得不写出跟接口中run方法一模一样的, 方法名, 返回值类型, 参数列表
- 这个时候, 才需要编写新线程具体要执行的内容.
思想的转变
- 以前的代码是
怎么做, 现在要强调的是做什么
转变之后
new Thread(() -> System.out.println("开启了一条新线程!~")).start();
2. Lambda表达式的格式
- Lambda其实就是匿名内部类的简化格式
格式
(参数) -> {代码}
(参数) : 一些参数
-> : 一个箭头
{代码} : 一段代码
将小括号中的参数, 传递给大括号中, 去使用
3. Lambda标准格式的转换过程
- (参数): Lambda中的小括号, 就是匿名内部类中重写方法的 参数列表
- {代码}: Lambda中的大括号, 就是匿名内部类中重写方法的 方法体
4. Lambda表达式的标准格式
举例Lambda的时候时, 会自己模拟写一个接口, 模拟一个方法, 方法的参数列表就是刚才创建的接口
而以后lambda的实际应用场景, 模拟的接口和方法, 都不是要我们自己写的.
我们要做的就是对于方法的调用
(1) 自定义无参无返回的lambda
public interface Cook {
void makeFood();
}
// ==================================================
public class Demo02_自定义无参无返回的lambda {
public static void main(String[] args) {
// 方法的调用
// 匿名内部类
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("吃饭啦!~");
}
});
// lambda
invokeCook(() -> {
System.out.println("吃晚饭啦!~");
});
// 省略格式
invokeCook(() -> System.out.println("吃晚饭啦!~"));
}
// 方法的参数列表是接口, 那么实际传入的就是它的实现类对象
private static void invokeCook(Cook cook) {
cook.makeFood();
}
}
(2) 自定义有参有返回的lambda
public interface Calculator {
int calc(int a, int b);
}
// ==================================================
public class Demo03_有参有返回的lambda {
public static void main(String[] args) {
// 匿名内部类
invokeCalc(10, 20, new Calculator() {
@Override
public int calc(int a, int b) {
return a + b;
}
});
// lambda
invokeCalc(234, 432, (int a, int b) -> {
return a + b;
});
// 省略格式
invokeCalc(234, 432, (a, b) -> a + b);
}
private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
System.out.println("结果是:" + result);
}
}
(3) 只有一个参数的lambda
public interface MyInter {
int getAbs(int n);
}
// ==================================================
public class Demo4_只有一个参数的lambda {
public static void main(String[] args) {
// 方法的调用
// 匿名内部类
printAbs(new MyInter() {
@Override
public int getAbs(int n) {
return Math.abs(n);
}
});
// lambda
printAbs((int n) -> {
return Math.abs(n);
});
// 省略格式
printAbs(n -> Math.abs(n));
}
private static void printAbs(MyInter mi) {
System.out.println("绝对值为: " + mi.getAbs(-100));
}
}
(4) Runnable的lambda
public class Demo05_Runnable {
public static void main(String[] args) {
// 匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("哈哈");
}
}).start();
// lambda
new Thread(() -> {
System.out.println("哈哈");
}).start();
// 省略格式
new Thread(() -> System.out.println("哈哈")).start();
}
}
(5) Comparator的lambda
public class Demo06_Comparator {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 3, 2, 4, 1, 5);
// 降序排序
// 匿名内部类
/*Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});*/
// lambda
Collections.sort(list, (Integer o1, Integer o2) -> {
return o2 - o1;
});
// 省略格式
Collections.sort(list, (o1, o2) -> o2 - o1);
System.out.println(list);
}
}
5. Lambda表达式的省略格式
省略原则: 可推导可省略
具体的省略场景
- 小括号中的数据类型, 可以省略
- 小括号中如果只有一个参数, 小括号可以省略
- 大括号中如果只有一条语句, 可以省略大括号和分号
- 大括号中如果只有一条返回语句, 可以省略大括号, 分号和return
6. Lambda表达式的使用前提
- 必须存在一个接口, 接口中有且只有一个抽象方法
- 该接口需要作为方法的参数列表
特殊情况: Comparator中有两个抽象方法,