Java8—Lambda
一、 Why Lambda
原因:
为了让代码更简洁,更优雅,优化程序。
Lambda表达式可以看做函数式编程的子集。
之前看过一位博主的写的一句便于理解的一种说法:
Lambda表达式,其实是一段可传递的代码。
它的本质是以类的身份,干方法的活。
博主:bravo1988
可以在知乎搜到他。
精辟!!!
二、Lambda的一些特性
例子:
假如现在有一个接口
接口:(接口多态)
public interface MyRunnable {
void run();
}
1、早期实现(策略模式)
实现类1
public class ByTrain implements MyRunnable {
@Override
public void run() {
System.out.println("去12306买了一张票");
System.out.println("坐火车...");
}
}
实现类2
public class ByAir implements MyRunnable {
@Override
public void run() {
System.out.println("在某App上订了飞机票");
System.out.println("坐飞机...");
}
}
这种方法非常不好,只能通过实现类的方式来新增实现。
调用类:
public class MyThread {
// 成员变量
private MyRunnable target;
public MyThread() {}
// 构造方法,接收外部传递的出行策略
public MyThread(MyRunnable target) {
this.target = target;
}
// MyThread自己的run(),现在基本不用了
public void run() {
System.out.println("去12306买了一张票");
System.out.println("坐火车...");
}
// 如果外部传递了出行策略,就会调用该策略里的run()
public void start() {
if (target != null) {
target.run();
} else {
this.run();
}
}
}
如果后续策略类太多,会发生“类爆炸”。
2、匿名内部类(Java8之前能做到的最好的优化)
public class Demo {
public static void main(String[] args) {
new MyThread(new MyRunnable() {
@Override
public void run() {
System.out.println("不用买票");
System.out.println("骑电瓶车...");
}
}).start();
}
}
也就是不用一直创建策略类
Java8使用Lambda改善
public class Demo {
public static void main(String[] args) {
new MyThread(() -> {
System.out.println("不用买票");
System.out.println("骑电瓶车...");
}).start();
}
}
我们会发现new MyThread()这个构造方法原本需要传递一个MyRunnable接口的子类对象(匿名类对象),但我们扔一个Lambda表达式进去,它也接受了,这说明Lambda表达式在身份上与匿名类对象等价。
并且我们会发现传进去的lambda表达式中最后干活的是那个sout语句,而sout语句是在方法中(方法是对代码块的封装),所以说Lambda表达式在作用上与方法等价。
三、lambda使用条件
接口要想接收Lambda表达式,必须是一个函数式接口(也就是有且只有一个抽象方法,因为Lambda不用写参数类型及返回类型就是因为接口只有一个抽象方法,因此可以通过上下文判断类型)。
所谓函数式接口,最核心的特征是:有且只有一个抽象方法。
Java8的Lambda都是基于上下文推导的,当一个接口只有一个方法时,推导结果是唯一确定的,但是方法不唯一时,无法推导得到唯一结果。
总结自:
知乎博主:bravo1988
的博客