一、含义:lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。
二、表达式形式:参数,箭头(->)以及一个表达式。如:
(String first,String second)->{
if (first.length()<second.length) return -1
else return 0
}
其中:如果可以推导出一个lambda表达式的参数类型,则可以忽略其类型。例如:
Comparator<String> comp = (first,second)->first.length()-second.length(); //表达式只有一行可以省略{}和return
三、变量作用域的问题
lambda表达式中可以访问外围的方法或类中的变量。例:
public static void repeatMessage(String text,int delay) {
ActionListener listener = event ->
{
System.out.println(text);
Toolkit.getDefaultToolkit().beep();
};
new Timer(delay,listener).start();
}
但是lambda表达式中不能改变引用变量的值,其意思理解为lambda表达式中捕获的变量必须实际上是最终变量,例如:下面的做法就是不和法的:
public static void countDown(int start,int delay){
int a = e->{
start--;//error 不能改变引用变量的值
return start;
}
}
public static void repeat(String text,Integer count) {
for (int i=1;i<=10;i++) {
a = e->{
System.out.println(i+":"+text);//error i不是最终变量
};
}
}
四、使用lambda的场景
1.使用lambda表达式实现Runnable,替换内部类
public class TestDemo {
/**
* 普通的Runnable
*/
public static void runTest() {
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println("I am runing");
}
};
new Thread(runnable).start();
}
/**
* 使用lambda表达式
*/
public static void runLambdaTest() {
new Thread(() -> System.out.println("I am runing")).start();
}
}
其中Runnable必须为函数式接口。对于只有一个抽象方法的接口,称之为函数式接口(例如:ActionListener、Comparator都是函数式接口)。
2.方法引用:如果我们想要调用的方法拥有一个名字,我们就可以通过它的名字直接调用它。
Comparator Name = Comparator.comparing(Person::getName);
此处无需再传入参数,lambda会自动装配成Person类型进来然后执行getName()方法,而后返回getName()的String
方法引用有很多种,它们的语法如下:
静态方法引用:ClassName::methodName
实例上的实例方法引用:instanceReference::methodName
超类上的实例方法引用:super::methodName
类型上的实例方法引用:ClassName::methodName
构造方法引用:Class::new
数组构造方法引用:TypeName[]::new
3.使用lambda表达式的重点是延迟执行。
使用延迟执行的原因:(1).在一个单独的线程中运行代码; (2).多次运行代码; (3)在算法的适当位置运行代码(例如,排序中的比较操作); (4).发生某种情况时执行代码(如,点击了一个按钮,数据到达,等等); (5).只在必要时才运行代码。
例如:重复一个动作n次,将这个动作和重复次数传递到一个repeat方法:
repeat(10,()->System.out.println("Hello World"));
public static void repeat(int n,Runnable action) {
for (int i=0; i<n;i++) {
action.run();
}
}
4.使用lambda遍历数组。
List features = Arrays.asList("a", "b", "c", "d");
features.forEach(n -> System.out.println(n));
5.使用lambda表达式对一个数组进行操作生成一个新的数组
List<Integer> oldList = Arrays.asList(1,2,3,4);
List<Integer> newList = oldList.stream().map(e -> e * 2).collect(Collectors.toList());