1. 前言
lambda表达式 是java8中出现的新语法,那么为什么我们要去使用一种新的语法?或者说为什么我们要把匿名内部类换成lambda表达式?
- Lambda是一个匿名函数,可以理解为一段可以传递的代码,将代码像数据一样进行传递,可以写出更加简介、更加灵活的代码。作为一宗更紧凑的代码风格,使Java的语言表达能力得到了提升.
2.最简单的例子
我们通过一个最简单的例子来查看lambda表达式与匿名内部类的写法区别.
//匿名内部类写法
@Test
public void test1(){
Comparator<Integer> com = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
}
//lambda表达式写法
public void lambda_test1(){
//o1,o2 为自定义参数,随意替换,意思是compare(Integer o1, Integer o2)方法中的第一个参数和第二个参数,可以写为(x, y) -> Integer.compare(x,y)
Comparator<Integer> com = (o1, o2) -> Integer.compare(o1,o2);
}
可以很明显的看出lambda表达式相比较之前的匿名内部类,逻辑清楚,代码简洁,很明显的表达了代码的含义,而最开始的匿名内部类很明显可以感受到有太多多余的代码,其中最关键的就一句话 return Integer.compare(o1,o2),,而其他代码都是多余代码,大大减少了代码的可阅读性.
具体业务中使用
基本数据
假如我们有一个Apple类,代码入下:
@Data //lombok插件自动setter getter
public class Apple {
private String name; //苹果名字
private Integer weight; //苹果重量
private Double price; //苹果价格
public Apple() {
}
public Apple(String name, Integer weight, Double price) {
this.name = name;
this.weight = weight;
this.price = price;
}
}
有一个List<Apple>,如下:
ArrayList<Apple> apples = (ArrayList<Apple>) Arrays.asList(
new Apple("红苹果",3,33.33),
new Apple("黄苹果",4,44.44),
new Apple("绿苹果",5,55.55),
new Apple("毒苹果",6,66.66)
);
需求来了
现在业务需求来了,我们需要筛选出价格大于50块钱的苹果.那么很明显我们的代码会是这样:
/**
* 筛选苹果价格大于50的方法
*/
@Test
public List<Apple> test2() {
List<Apple> filterApple = new ArrayList<>();
for (Apple apple : apples) {
if(apple.getPrice() > 50)
filterApple.add(apple);
}
return filterApple;
}
如果过了两天,项目经理来说我们现在需要筛选苹果重量大于5的方法,那么我们就会复制粘贴上一段代码,然后修改其中的判断部分,代码入下:
/**
* 苹果重量大于5
*/
@Test
public List<Apple> test3() {
List<Apple> filterApple = new ArrayList<>();
for (Apple apple : apples) {
if(apple.getWeight() > 5)
filterApple.add(apple);
}
return filterApple;
}
策略模式优化
可以很明显看到这两端代码,几乎完全是一致的,代码重复率非常之高,在lambda表达式之前,人们只能用设计模式来解决这个问题,比如策略模式,我们会创建一个filter接口,让需要过滤的方法继承filter接口,实现具体的过滤规则.
/**
* 通用过滤方法
* @param apples 需要过滤的List
* @param myFilter 具体过滤规则
* @return 过滤结果
*/
public List<Apple> filterApples(List<Apple> apples, MyFilter myFilter){
List<Apple> filterApple = new ArrayList<>();
for (Apple apple: apples) {
if (myFilter.test(apple))
filterApple.add(apple);
}
return filterApple;
}
//过滤接口
public interface MyFilter<T> {
boolean test(T t);
}
而这个时候我们再次实现最开始项目经理提出来的两个需求之后,即可以用通用过滤接口解决问题.
/**
* 价格大于50 ,策略设计模式改进方法
* @return
*/
@Test
public List<Apple> test5() {
List<Apple> filterApple = filterApples(this.apples, new MyFilter<Apple>() {
@Override
public boolean test(Apple apple) {
return apple.getPrice() > 50;
}
});
return filterApple;
}
/**
* 重量大于5 ,策略设计模式改进方法
* @return
*/
@Test
public List<Apple> test6() {
List<Apple> filterApple = filterApples(this.apples, new MyFilter<Apple>() {
@Override
public boolean test(Apple apple) {
return apple.getWeight() > 5;
}
});
return filterApple;
}
lambda表达式优化
这样我们就实现了代码的复用,大家肯定已经发现了,还可以更加加以改进,那就是使用我们最开始提到的lambda表达式对代码进行优化,让代码更加可读,简洁!
/**
* 价格大于50 ,lambda改进方法
* @return
*/
@Test
public List<Apple> lambda_test5() {
List<Apple> filterApple = filterApples(this.apples, (MyFilter<Apple>) apple -> apple.getPrice() > 50);
return filterApple;
}
/**
* 重量大于5 ,lambda改进方法
* @return
*/
@Test
public List<Apple> lambda_test6() {
List<Apple> filterApple = filterApples(this.apples, (MyFilter<Apple>) apple -> apple.getWeight() > 5);
return filterApple;
}
Stream 搭配lambda表达式优化
相信大家对lambda表达式有一定的了解了,不过其实在实际开发中,遇到这两种需求,可以使用java8中的stream搭配lambda表达式轻松解决.
/**
* 使用stream 搭配lambda表达式
* @return 过滤结果
*/
@Test
public List<Apple> test7() {
List<Apple> appleList = apples.stream() //List Map等都能转化为Stream
.filter(apple -> apple.getWeight() > 5) //类似于我们的匿名内部类filter的作用
.collect(Collectors.toList()); //收集器,将Stream 变为List
return appleList;
}
小结
- Lambda是一个匿名函数,可以理解为一段可以传递的代码,将代码像数据一样进行传递,可以写出更加简介、更加灵活的代码。作为一宗更紧凑的代码风格,使Java的语言表达能力得到了提升.
现在我们对这段话的含义的理解稍稍加深了一些, 通过一些简单的小例子,可以清楚的看到在java8 中使得我们的开发便捷了不知道多少.
网友评论