0. 前言
Lambda是JAVA8 之后推出的一种新特性,本质是一种"语法糖",精简了语法,主要针对的是匿名内部类的语法精简。
例如,当我们要实现使用FileFilter 文件过滤器对文件进行过滤时,因为FileFilter是一个接口,不能直接new对象出来,所以我们要使用匿名内部类的方式对FileFilter的accept方法进行重写并创建它的子类。
以下是FileFilter源码:
public interface FileFilter {
/**
* Tests whether or not the specified abstract pathname should be
* included in a pathname list.
*
* @param pathname The abstract pathname to be tested
* @return <code>true</code> if and only if <code>pathname</code>
* should be included
*/
boolean accept(File pathname);
}
匿名内部类的方式创建FileFilter子类:
//使用匿名内部类
FileFilter ff = new FileFilter() {
@Override
public boolean accept(File pathname) {
return false;
}
};
Lambda表达式就是使用匿名内部类时,对语法的一种精简。下面我们来学习。
1. Lambda 基本用法
1.1 使用条件
所实现接口中只能有一个抽象方法,例如我们的FileFilter 接口中就只有一个accept方法。
如果某接口中有多个抽象方法,那么Lambda将不适用。
1.2 语法与例子
(1)基本语法
(参数列表)->{
方法体
}
举个例子:
FileFilter filter1 = (File pathname) -> {
return false;
};
对比一下:
FileFilter filter1 = new FileFilter() {
public boolean accept(File pathname) {
return false;
}
};
可见,lambda表达式省略了new、以及方法重写的声明,并用了一个 箭头 -> 在表达式中。
(2)极致精简
以上面的文件过滤器为例子,实际上Lambda表达式还能再精简
a : 能省略掉参数的类型
//参数类型可以不写
FileFilter filter2 = (pathname) ->{
return false;
};
b : 当参数只有一个时还能再省略
//当参数只有一个时
FileFilter filter3 = pathname -> {
return false;
};
c : 当方法体只有一句话时,直接箭头指向返回值
//还能省略!当只有一句话时,可以连大括号+return 也不写
FileFilter filter4 = pathname -> false;
(3)综合举例
例如,我们使用文件过滤器 实现对包含某个名字的文件进行过滤时,可以写成如下:
File [] fs = new File("./src/file").
listFiles(pathname -> pathname.getName().contains("M")
);
//遍历一下结果
for (File subs : fs){
System.out.println(subs);
2. 聚合操作
上面的章节我们结合FileFilter 学习了Lambda 的基本用法,本章节我们结合Lambda简单了解一下聚合操作。
聚合操作是JDK8 以后,对集合进行高效遍历、筛选的一种操作。
聚合操作的过程中,涉及stream 和 管道 的一些概念:
Stream 指的是一系列元素,管道分为:管道源、中间操作和结束操作。
举个小例子,我们先定义一个实验类,再将它插入集合,进行聚合操作。
实验类:
/**
* @Author Sharry
* @Time 2022年8月23日 下午5:31:25
* @Version 1.0
* Description 聚合操作样本
*/
public class CollPerson {
private Integer age;
private String name;
public void sayHello() {
System.out.println("Hello");
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CollPerson(Integer age, String name) {
super();
this.age = age;
this.name = name;
}
public CollPerson() {
}
@Override
public String toString() {
return "age:"+age+" name:"+name;
}
}
聚合操作:
public static void main(String[] args) {
//随机age数据,往集合中插入元素
Random r = new Random();
ArrayList<CollPerson> al = new ArrayList<>();
for(int i = 0 ; i < 5 ; i++) {
al.add(new CollPerson(r.nextInt(50),"person"+i));
}
System.out.println(al);
//聚合操作,筛选出age<30的对象
al.stream().filter(cp -> cp.getAge()<30).forEach(cp -> System.out.println(cp.toString()));
}
3. 总结
Lambda 精简了 匿名内部类的使用,如果熟练运用,可以提高开发效率。
但是,Lambda也有局限性:可读性差,对新手不友好;只是语法糖,编译时内部还是要还原为原有的匿名内部类实现方式,使用时还要考虑IDE是否支持这种语法,如果我们使用比较旧的IDE,如Eclipse,有时还需要对Eclipse进行多一层配置;Lambda的使用条件狭窄,只能对只有一个抽象方法的接口使用…
最后, 无论 Lambda 是否过于局限,是否可读性差,异或极大简便了代码,我们都应该多少学习、了解一下,然后选择适合我们的方式进行开发。