Lambda表达式
今天在网上找资料的时候看到个很有趣的东西
就是这个
xxx.addActionListener(e -> {
//内容
});
作为一个还在学习中的我,看到这个代码块的时候觉得很新奇
因为平时写监听器的时候都是像下面这么写的
xxx.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//内容
}
});
正常都是这么写的对吧,但是他就不一样。
然后我就去百度找了下,发现搜(e->{})很难搜出来
找了小一会才知道这个是Java8的一个大亮点:Lambda表达式
百度原话
:
正如你所看到的,使用Lambda表达式不仅让代码变的简单、而且可读、最重要的是代码量也随之减少很多。然而,在某种程度上,这些功能在Scala等这些JVM语言里已经被广泛使用。
并不奇怪,Scala社区是难以置信的,因为许多Java 8里的内容看起来就像是从Scala里搬过来的。在某种程度上,Java 8的语法要比Scala的更详细但不是很清晰,但这并不能说明什么,如果可以,它可能会像Scala那样构建Lambda表达式。
一方面,如果Java继续围绕Lambda来发展和实现Scala都已经实现的功能,那么可能就不需要Scala了。另一方面,如果它只提供一些核心的功能,例如帮助匿名内部类,那么Scala和其他语言将会继续茁壮成长,并且有可能会凌驾于Java之上。其实这才是最好的结果,有竞争才有进步,其它语言继续发展和成长,并且无需担心是否会过时。
1、了解一下Lambda表达式
1、Lambda表达式的结构
- 一个 Lambda 表达式可以有零个或多个参数
- 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
- 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
- 空圆括号代表参数集为空。例如:() -> 42
- 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
- Lambda 表达式的主体可包含零条或多条语句
- 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
- 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空
2、Lambda 表达式的使用
举一个简单的例子
1.1、比如我们对Map 的遍历
传统方式遍历如下:
Map<String, String> map = new HashMap<>();
map.put("A", "AA");
map.put("B", "BB");
map.put("C", "CC");
map.put("D", "DD");
System.out.println("Map正常遍历:");
for (String key : map.keySet()) {
System.out.println("\nkey=" + key + ",value=" + map.get(key));
}
使用Lambda进行遍历:
System.out.println("map使用Lambda遍历:");
map.forEach((key, value) -> {
System.out.println("\nkey=" + key + ",v=" + value);
});
1.2、List也同理,不过List还可以通过双冒号运算符遍历:
List<String> list = new ArrayList<String>();
list.add("A");
list.add("BB");
list.add("CCC");
list.add("DDDD");
System.out.println("\nlist使用Lambda遍历:");
list.forEach(v -> {
System.out.println(v);
});
System.out.println("\nlist双冒号运算符遍历:");
list.forEach(System.out::println);
输出结果:
Map正常遍历:
key=A,value=AA
key=B,value=BB
key=C,value=CC
key=D,value=DD
Map正常遍历:
key=A,value=AA
key=B,value=BB
key=C,value=CC
key=D,value=DD
list使用Lambda遍历:
A
BB
CCC
DDDD
list双冒号运算符遍历:
A
BB
CCC
DDDD
1.3、Lambda代替匿名内部类
Lambda除了在for循环遍历中使用外,它还可以代替匿名的内部类。
比如下面这个例子的线程创建:
//使用普通方式创建
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("普通创建!");
}
};
//使用Lambda创建
Runnable r2 = ()-> System.out.println("Lambda创建!");
注: 这个例子中使用Lambda表达式的时候,编译器会自动推断:根据线程类的构造函数签名 Runnable r { },将该 Lambda 表达式赋Runnable 接口。
1.4、Lambda 表达式与匿名类的区别
使用匿名类与 Lambda 表达式的一大区别在于关键词的使用。
对于匿名类,关键词 this 解读为匿名类。
而对于 Lambda 表达式,关键词 this 解读为写就 Lambda 的外部类。
Lambda表达式使用注意事项
Lambda虽然简化了代码的编写,但同时也减少了可读性。