简介
HI!小伙伴们,好久没见了,4 月份开始断更,中途有点事儿,今天开始更新了,整理一篇 Lamda 表达式演化过程,希望喜欢的一如既往的支持!
image.png
传统集合过滤
现在有 2 个需求:在一组学生集合中,1.找出年龄大于 20 学生;2.找出分数小于 70 的学生;下面让我们看看代码吧!
/**
* @author :jiaolian
* @date :Created in 2021-07-12 15:14
* @description:学生测试
* @modified By:
* 公众号:叫练
*/
public class Student {
//姓名
private String name;
//年龄
private int age;
//分数
private double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
复制代码
List<Student> students = Arrays.asList(
new Student("张三",21,58),
new Student("李四",23,88),
new Student("王五",19,68),
new Student("叫练",25,78),
new Student("jiaolian",16,98)
);
//需求:1.找出年龄大于20学生;2.找出分数小于70的学生
@Test
public void test1() {
List<Student> stus = findStudentByAge();
System.out.println(stus);
System.out.println("===========");
List<Student> stus1 = findStudentByScore();
System.out.println(stus1);
}
//通过年龄过滤学生
public List<Student> findStudentByAge() {
List<Student> stus = new ArrayList<>();
for (int i=0; i<students.size(); i++) {
if (students.get(i).getAge() > 20) {
//将年龄大于20学生放入stus里
stus.add(students.get(i));
}
}
return stus;
}
//通过分数过滤学生
public List<Student> findStudentByScore() {
List<Student> stus = new ArrayList<>();
for (int i=0; i<students.size(); i++) {
if (students.get(i).getScore() < 70) {
//将找出分数小于70的学生放入stus里
stus.add(students.get(i));
}
}
return stus;
}
复制代码
如上代码:代码逻辑比较简单,findStudentByAge() 方法是通过年龄过滤学生,在 students 学生集合中通过循环过滤出大于年龄 20 的学生放入新的集合 stus 中,最终返回 stus 对象,同理,通过分数过滤学生也是这样,在测试方法 test1 中,调用 findStudentByAge()和 findStudentByScore();最终打印输出结果如下:
image.png
代码的结果我们输出了,结果输出没有问题,但是看上去有些臃肿,因为除了过滤条件外,for 循环等其他的好像都是重复的,如果我们需要再增加一个通过姓名过滤学生,又得写一个方法。针对已有代码,下面我们看看策略模式如何解决!
演化 1:接口策略模式
我们新增一个处理学生集合的接口
/**
* 学生处理接口
*/
public interface StudentHandler<T> {
//处理学生
boolean handlerStu(T t);
}
复制代码
/**
* @author :jiaolian
* @date :Created in 2021-07-12 15:42
* @description:处理学生年龄大于20
* @modified By:
* 公众号:叫练
*/
public class HandlerAge implements StudentHandler<Student> {
@Override
public boolean handlerStu(Student student) {
return student.getAge()>20;
}
}
复制代码
@Test
public void test2() {
List<Student> res = getStudents(students,new HandlerAge());
System.out.println(res);
}
/**
* 通过条件过滤学生
* @param stus
* @param studentHandler
* @return
*/
public List<Student> getStudents(List<Student> stus,StudentHandler<Student> studentHandler) {
List<Student> res = new ArrayList<>();
for (int i=0; i<stus.size(); i++) {
//接口条件
if (studentHandler.handlerStu(stus.get(i))) {
res.add(stus.get(i));
}
}
return res;
}
复制代码
如上代码:新建 StudentHandler 接口处理学生,HandlerAge 实现类实现了 StudentHandler,用于过滤学生年龄大于 20 的对象,getStudents 方法接收 stus 和 studentHandler 对象分别表示原始学生对象和接口实现 new HandlerAge(),调用该方法最终打印学生年龄大于 20 的对象,和上面结果一致。如果现在我们需要通过分数处理,我们新增一个 HandlerScore 类实现 StudentHandler 接口就可以了,大家可以自行测试下,但是有个缺点,类变多了。下面我们看看匿名内部类如何实现过滤分数小于 70 的学生。
演化 2:匿名内部类
@Test
public void test3() {
//匿名内部类实现
List<Student> res = getStudents(students, new StudentHandler<Student>() {
@Override
public boolean handlerStu(Student student) {
return student.getScore() <70;
}
});
System.out.println(res);
}
复制代码
如上代码:该匿名对象实现了过滤分数小于 70 的学生。
演化 3:lamda 表达式
上面的代码已经足够简单,但自从 JDK1.8 开始支持了 Lambda,我们针对上面的代码再做一次优化。
@Test
public void test4() {
List<Student> res = getStudents(students, student -> student.getScore() <70);
System.out.println(res);
}
复制代码
如上代码:student -> student.getScore() <70 注意改代码格式就是 Lamda 格式,左边表示参数,如果有多个参数需要用括号表示,右边是实现过程,看!写法上非常简单,注意:lamda 需要函数接口支持:那什么是函数接口呢,只有一个抽象方法的接口称为函数接口。他的好处是简化表达,代码更通俗易懂,同时需要 jdk1.8 以上版本支持哦!
总结
好啦,今天我们就讲到这里,希望大家有疑问可以提问,欢迎和我交流。我是【公众号:叫练】,边叫边练;喜欢的可以加关注哦!再次感谢大家的观看支持。
评论