lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。在解释java为什么引入lambda表示式之前,不妨先回想一下,之前我们是怎么实现代码块的传递的?
案例1 实现定时指定任务
package learnspring.learnspring;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
/**
* @author xzy
* @date 2020-03-24 20:01
* 说明:
*/
public class Worker implements ActionListener {
/**
* Invoked when an action occurs.
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
//需要定时执行的代码,下面以输出当前时间为例。
Date date = new Date();
System.out.println(date);
}
public static void main(String[] args) {
ActionListener work = new Worker();
Timer timer = new Timer(1000, work);
timer.start();
while (true){}
}
}
案例2 实现字符串数组按照字符串长度排序
package learnspring.learnspring;
import java.util.Arrays;
import java.util.Comparator;
/**
* @author xzy
* @date 2020-03-24 20:11
* 说明:
*/
public class LengthComparator implements Comparator<String> {
/**
* @param o1 - 字符串1
* @param o2 - 字符串2
* @return - 正数:o1>=o2 负数:o1<o2
*/
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
public static void main(String[] args) {
String[] strings = new String[]{"hello", "world!", "java", "lambda"};
Arrays.sort(strings, new LengthComparator());
System.out.println(Arrays.toString(strings));
}
}
两个例子有一些共同点,都是将代码块传递给某个对象(一个定时器,或一个sort方法),代码块会在将来的某个时间被调用。
在此之前,在java中传递一个代码块并不容易,不能直接传递代码块。Java是一种面向对象语言,所以必须构建一个对象,这个对象需要有一个方法能够包含所需的代码。借助lambda表达式,只需要下面的代码即可实现案例2的功能。
public static void main(String[] args) {
String[] strings = new String[]{"hello", "world!", "java", "lambda"};
Arrays.sort(strings, (String s1, String s2) -> {
return s1.length() - s2.length();
});
System.out.println(Arrays.toString(strings));
}
如上面的代码所展示的那样,lambda表达式就是一个代码块,以及必须传入代码的变量规范。
一般的lambda表达式形式为:
( 参数 )-> 表达式
如果需要完成的工作无法用一个表达式完成,可以像方法一样,用{}将需要执行的语句框起来:
( 参数 )-> {
表达式1;
表达式2;
表达式3;
}
需要注意的几点:
- 如果没有参数,需要保留空括号。
()->{...}
如果可以推导出参数类型,可以忽略其类型。
Comparator<String> comparator = (s1,s2)->{s1.length()-s2.length();}
如果方法只有一个参数,而且这个参数的类型是可以推到出来的,那么可以省去小括号。
ActionListener listener = event->{......}
不需要指定lambda表达式的返回值类型。lambda表达式的返回值类型总是根据上下文推导得出。
在lambda表达式中,只能引用值不会改变的变量。
lambda表达式中声明一个与局部变量同名的参数或局部变量是不合法的。
在一个lambda表达之中使用this关键字时,是指创建这个lambda表达式的方法的this参数。
《Java核心技术》学习笔记
原文:https://www.cnblogs.com/KenBaiCaiDeMiao/p/12861489.html