lambda表达式与事件处理
lambda表达式是JDK8中新增的重要特性,它支持将代码作为方法参数,允许使用更简洁的代码来创建只有一个抽象方法的接口的实例,增加了Java语言的表达能力。
lambda表达式
Java语言中,成员方法的定义形式为
[修饰符] 返回值数据类型 方法名(参数列表)[throws 异常列表]{
方法体 }
lambda表达式本质上是一种匿名方法,与成员方法的定义形式相比,它更简洁,除了没有方法名以外,还省略了修饰符、返回值异常、异常的声明,在某些情况下还可以省略参数类型。lambda表达式的形式为
(参数列表)-> {方法体}
其中,“->”是运算符,称为lambda运算符。它将lambda表达式分为两部分,左侧的参数列表是匿名方法的形参,右侧为方法体,也称为lambda体。例如:
(int x,int y)->{
System.out.println(x);
System.out.println(y);
return x+y;
}
这个lambda表达式有两个参数,参数类型为int,其作用类似于下面的成员方法:
public int add(int x,int y){
System.out.println(x);
System.out.println(y);
return x+y;
}
当Java编译器能够从上下文推断出参数类型时,可以省略参数的类型。例如:
(x,y)->{
System.out.println(x);
System.out.println(y);
return x+y;
}
当参数列表只有一个参数时,圆括号可以省略,例如:
x->{
System.out.println(x);
return x++;
}
当参数为空时,圆括号不能省略,例如:
()->{
System.out.println("Hello World!");
}
当方法体只包含一条语句时,可以省略方法体的{},如果这一条语句是return语句时,可以省略关键字return和末尾的分号。例如:
(int x,int y)->x+y
函数式接口
lambda表达式与函数式接口紧密相关。函数式接口(Functional Interface)是指仅包含一个抽象方法的接口,例如ActionListener接口,ItemListener接口都属于函数式接口。一个函数式接口的定义如下:
interface MyInterface{
int add(int x,int y);
}
其中,add()方法是抽象方法,而且是MyInterface接口中唯一的抽象方法,因此MyInterface接口是一个函数式接口。
在Java语言中,lambda表达式可以用来实现函数式接口中的抽象方法。或者说,任何一个可以接受函数值接口的实例对象的地方,都可以用lambda表达式。在执行lambda表达式时,会自动创建一个实现了函数式接口的类的实例。可以这样理解,lambda表达式将类(实现了接口的匿名类)的定义、对接口中抽象方法的实现、实例的创建融为一体。例如:
MyInterface mi=(x,y)->x+y;
赋值运算符右侧应该是MyInterface接口的实例,这里使用了lambda表达式,它实现了MyInterface接口中的add()方法.由于根据MyInterface接口中的add()方法的参数类型可以推断出lambda表达式中的参数类型,因此省略了参数类型。另外,方法体中有一条语句return x+y,将其简化为x+y。执行这条语句时,会自动创建一个MyInterface接口的实例赋给mi,这个实例拥有已经实现了的add()方法。与这条语句等价的代码为
MyInterface mi=new MyInterface(){
public int add(int x,int y){
return x+y;
}
}
其中,赋值运算符右侧包含了匿名类(实现了MyInterface接口)的定义及其实例的创建。
【例】函数式接口与lambda表达式应用实例
interface MyInterface{ //函数式接口
int add(int x,int y);
}
public class App{
public static void main(String[] args){
MyInterface mi=(x,y)->x+y; //使用lambda表达式实现抽象方法
System.out.println(mi.add(1,2)); //调用add()方法
}
}
程序运行结果为
3
使用lambda表达式进行事件处理
如果事件监听器接口是函数式接口,那么创建监听器时可以使用lambda表达式。
【例】使用lambda表达式进行事件处理实例。
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class EventDemo{
JFrame frame;
JButton okButton,cancelButton;
EventDemo(String title){
frame=new JFrame(title);
frame.setSize(260,150);
frame.setLayout(new FlowLayout());
okButton=new JButton("确定");
cancelButton=new JButton("取消");
frame.add(okButton);
frame.add(cancelButton);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建匿名类进行“确定”按钮的事件处理
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.setTitle("点击了确定按钮");
}
});
//使用lambda表达式进行“取消”按钮的事件处理
cancelButton.addActionListener(e->frame.setTitle("点击了取消按钮"));
}
}
public class app {
public static void main(String[] args) {
// TODO Auto-generated method stub
new EventDemo("事件响应");
}
}
//具体实现效果请自己验证
说明:程序中,“确定”按钮的事件处理仍然使用匿名类 ,“取消”按钮的事件处理应用了lambda表达式,它将监听器类的定义、 actionPerformed()方法的实现及监听器对象的创建融为一体。两种方法的实现效果等价,但是用lambda表达式后省略了编译器能够推断出来的内容,从而突出了重要的事件处理的代码,使程序更让你更加简洁。
最后,lambda表达式的功能非常强大,有兴趣可以进一步学习。