[lambda官方文档][1]
介绍英语不好,翻译的不准,英语好的请直接看官方文档。
Lambda表达式语法Lambda表达式是一个Java8中一个新且重要的特点。它提供清晰简洁的表达式去表现只有一个方法的接口。Lambda表达式也改进了Collection库,使其更容易对Collection进行迭代、筛选、提取数据。
参数列表 箭头符号 内容
(int x, int y) -> x+y
内容(x+y)可以是一个表达式,也可以是一个代码块。如果是表达式,返回值就是这个表达式的结果。如果是代码块,则需要使用return来进行结果返回。
举例:
我们有一个接口A
interface A{
int sum(int x,int y); //该接口有一个未实现的方法。
}
只包含一个表达式的lambda表达式
public static void main(String[] args){
A a=(int x, int y)-> x+y;
System.out.println(a.sum(1,2)); //输出结果为3.
}
包含代码块的lambda表达式
public static void main(String[] args) {
A a=(int x, int y)-> {
System.out.print("x+y=");
return x+y;
};
System.out.println(a.sum(1,2)); //输出结果为 x+y=3
}
Lambda示例此lambda表达式包含两个参数,分别是x和y,他们的功能是输出"x+y=",并返回x+y的值。
使用lambda实现Runnable接口
public static void main(String[] args) {
//使用匿名类实现Runnable接口
Runnable r1=new Runnable() {
@Override
public void run() {
System.out.println("hello r1");
}
};
//使用Lambda表达式实现Runnable接口
Runnable r2= () -> System.out.println("hello r2");
r1.run();
r2.run();
// 输出结果:
// hello r1
// hello r2
}
Runnable接口只有一个未实现的方法run(), 所以没有参数,参数列表即为(), run()方法的内容为一个表达式(System.out.println("hello r2")),所以不需要加大括号"{}",返回值为void,并且sout的返回值也是void,两者符合。所以可以写为 () -> System.out.println("hello r2");
Comparator Lambda
官方示例的第二个,这里我进行了简化。并且详细说明一下。
<br>
将Comparator简化为以下:
@FunctionalInterface
interface Comparator{
boolean compare(int a, int b);
boolean equals(Object obj);
default int max(int a,int b){
return (a >= b) ? a : b;
}
}
可以使用下面代码,使用lambda表达式实现compare方法。
public static void main(String[] args) {
//使用匿名类实现
{
Comparator comparator=new Comparator() {
@Override
public boolean compare(int a, int b) {
return a>b;
}
};
System.out.println(comparator.compare(1,2));
}
//使用Lambda表达式
{
Comparator comparator=(int a,int b)-> a>b;
System.out.println(comparator.compare(1,2));
}
}
可能会有以下疑问:
1. Comparator有两个未实现的方法(compare和equals),但是可以使用Lambda表达式。
解释:这个问题可以查看@FunctionalInterface注解源码看出,里面有这样一段话
- Conceptually, a functional interface has exactly one abstract
- method. Since {@linkplain java.lang.reflect.Method#isDefault()
- default methods} have an implementation, they are not abstract. If
- an interface declares an abstract method overriding one of the
- public methods of {@code java.lang.Object}, that also does
- <em>not</em> count toward the interface's abstract method count
- since any implementation of the interface will have an
- implementation from {@code java.lang.Object} or elsewhere.
大致意思就是Object的公共方法不会被算在其中,像equals,toString,hashCode这样的方法。
第二个问题
2.这是一个接口,但是max方法却有具体实现。
解释:在Java8中,接口可以提供默认的方法实现。这些被默认实现的也不会算在lambda表达式中的重写方法中。所以Comparator接口相当于只有一个未实现的方法compare。
Listener Lambda
官方示例3,使用lambda表达式实现按钮点击监听器
public static void main(String[] args) {
JButton testButton = new JButton("测试按钮");
testButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
System.out.println("匿名类实现按钮点击事件");
}
});
testButton.addActionListener(e -> System.out.println("Lambda表达式实现按钮点击事件"));
// 启动窗口
JFrame frame = new JFrame("Listener Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(testButton, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
Lambda表达式和Collections()声明中可以不写类型,如(int a,int b)-> a+b, 可以写为 (a,b)->a+b
使用lambda表达式进行遍历
public static void main(String[] args) {
List<String> list=Arrays.asList(new String[]{"a1","b2","c3"});
list.forEach(s-> System.out.println(s));
}
forEach为 Iterable接口的方法。 其中List继承了Iterable接口。
先写到这里