前言
本文通过一系列典型应用的需求,引出Lambda。实际体验Lambda
的优势
需求1:按照颜色筛选苹果
package com.example.java.part01;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @Author sherry
* @Description
* @Date Create in 2019-04-21
* @Modified By:
*/
public class MainPart01 {
public static void main(String[] args) {
List<Apple> apples = createApples();
System.out.println(apples);
List<Apple> greenApples = filterApplesByColor(apples, "绿");
System.out.println(greenApples);
}
/**
* 按照颜色筛选苹果
* @param apples
* @param color
* @return
*/
private static List<Apple> filterApplesByColor(List<Apple> apples, String color) {
List<Apple> list = new ArrayList<>();
for (Apple apple : apples) {
if (Objects.equals(color, apple.getColor())) {
list.add(apple);
}
}
return list;
}
/**
* 初始化一堆苹果
*
* @return
*/
private static List<Apple> createApples() {
List<Apple> list = new ArrayList<>();
for (int i = 0; i < 30; i++) {
Apple apple = Apple.builder()
.color(i % 2 == 0 ? "红" : "绿")
.weight(i)
.build();
list.add(apple);
}
return list;
}
}
需求2:按照质量筛选苹果
/**
* 按照质量筛选苹果
* @param apples
* @param weight
* @return
*/
private static List<Apple> filterApplesByWeight(List<Apple> apples, int weight) {
List<Apple> list = new ArrayList<>();
for (Apple apple : apples) {
if (weight > apple.getWeight()) {
list.add(apple);
}
}
return list;
}
分析1:抽象判断方法
我们发现,按照上面的方式,每一种属性的筛选,都需要编写一个筛选方法
我们可以把筛选这个动作作为参数传递给filter
方法,这样,每次根据判断内容的不同,传递不同的筛选方法对象即可
优化
public static void main(String[] args) {
List<Apple> apples = createApples();
System.out.println(apples);
List<Apple> apples1 = filterApples(apples,new AppleColorPredicate("绿"));
System.out.println(apples1);
}
/**
* 苹果筛选
* @param apples
* @param applePredicate
* @return
*/
private static List<Apple> filterApples(List<Apple> apples, ApplePredicate applePredicate) {
List<Apple> list = new ArrayList<>();
for (Apple apple:apples){
if (applePredicate.test(apple)){
list.add(apple);
}
}
return list;
}
- 接口
public interface ApplePredicate {
/**
* 判断指定的苹果是否满足需求
* @param apple
* @return
*/
boolean test(Apple apple);
}
然后编写AppleColorPredicate
和AppleWeightPredicate
,实现ApplePredicate
接口,分别做到按照颜色和质量进行苹果筛选功能
分析2:匿名函数
在分析1中,我们已经对代码进行了优化,但是还不够简洁。
分析1之后,我们其实是把苹果的判断逻辑,封装到了接口实现类中。
这个在有限个判断属性的时候还行,如果属性多,再加上多个属性的组合判断,那么这种实现类就会非常多。
这个时候,我们就想到了匿名函数,如对于颜色的筛选,可以改写为
List<Apple> apples1 = filterApples(apples, new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return "绿".equals(apple.getColor());
}
});
如果使用Lambda表达式,就只需要一行代码
List<Apple> apples1 = filterApples(apples, apple -> "绿".equals(apple.getColor()));
分析3:参数类型化
现在,我们的ApplePredicate
只能筛选苹果,我们可以通过参数类型化,可以实现对所有类型的元素进行判断
public interface Predicate<T> {
/**
* 判断指定的对象是否满足需求
* @param t
* @return
*/
boolean test(T t);
}
至此,一个比较优良的代码就已经初见雏形了。
满足了代码的简洁性,逻辑的清晰性,以及满足后续迭代变更的便捷