介绍
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
重点
1. 函数接口FunctionInterFace
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以被隐式转换为 lambda 表达式。
Lambda 表达式和方法引用(实际上也可认为是Lambda表达式)上。
lambda表达式,是指在方法中实现函数接口,或说将函数接口中的方法实现,这样看来,函数的实现就像是方法的一个参数。
也就是把函数作为方法的参数。你无需纠结lambda表达式中参数列表中值的来源,因为他只是方法/函数的实现,而不是方法/函数的调用!我们不需要细究调用这个函数时,参数的来源。
我们现在把lambda表达式实现的函数接口的方法叫函数,把能使用lambda的方法就叫方法。
Eg:
var Timer=new Timer(1000,event->
System.out.println("The time is "+new Date())
);
我们来看Timer的此构造器
public Timer(int delay, ActionListener listener) {
super();
this.delay = delay;
this.initialDelay = delay;
doPostEvent = new DoPostEvent();
if (listener != null) {
addActionListener(listener);
}
}
我们将参数一一对应。
Lambda表达式对应的是ActionListener listener。这是一个只有一个抽象方法的接口。
public interface ActionListener extends EventListener {
/**
* Invoked when an action occurs.
* @param e the event to be processed
*/
public void actionPerformed(ActionEvent e);
}
我们回顾下lambda表达式
event->
System.out.println("The time is "+new Date()
这是简化后的表达式,简化前应该是
(AcTionEvent event)->{
System.out.println("The time is "+new Date()
}
所以lambda表达式中的参数列表的event就是函数的参数列表中的ActionEvent e
函数: public void actionPerformed(ActionEvent e);
2. 理解
那么只看lambda表达式,会思考这个参数哪里来,或说值是什么?
总结一下,能使用lambda的方法,会提供一个接口“对应”表达式,然后表达式会实现接口里的方法/函数,由于是函数接口,方法只有一个,所以lambda的函数实现也只有一个(肯定不能一次两个)。那么我们在使用这个方法,例如构造器,这个接口参数,我们肯定要放入一个实现类或匿名类或null啊,总之要实现这个接口参数。
假如不用lambda表示式,我们如何实现这个接口参数。
匿名类
var Timer=new Timer(1000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("The time is "+new Date())
}
}
}
);
或者我们创建一个类叫TimerEvent实现ActionListener接口以及里面的actionPerformed方法
就变成了
var Timer=new Timer(1000,new TimerEvent());
而函数就在TimerEvent里实现了。
那我们有没有更简单的方式来为Timer的构造方法里的ActionListener参数提供实例呢?
那就是lambda表示,它直接实现了函数接口的函数,当然你实现了接口方法就代表你得实例化这个接口,你实现了接口你就得实现接口方法。而我没必要为一个函数单独分类(就像TimerEvent),所以lambda直接就实现函数---->方法都实现了,那肯定有了接口的实现类,但你不能显式(new XXX)看见罢了。
3. 总结
Lambd表达式是对方法中函数参数(函数接口)的函数实现。从而方法可以调用该函数(通过lambda实现了的接口)
所以要用lambda,该方法得有一个参数代表函数也就是函数接口,当我们要使用这个方法时候,这个接口参数肯定要实例化(毕竟java面向对象)。而lambda实现了函数接口中的函数,从而实例化了接口,然后这个函数作为方法参数任方法调用函数。
Lambda本质就是接口实现,不过是在方法中对方法的接口参数进行实现。再细致点就是对方法接口参数的实现,针对性强点就是实现函数作为方法参数。
随用随实现,我甚至可以多次调用同一方法,并使用不同的lambda表达式对方法的同一接口参数进行不同实现,而我没必要生产多个不同实现类来new注入到方法,也懒得多次在方法中生产匿名类(这和生产实现类差不多的代码量)。而我们只需要
(Parameter1,Parameter2)->{
~~~~~~
}
(接口中方法的参数列表)->{
方法体
}
来实现方法要调用的函数。