写点什么

Lamda(拉姆达)表达式演化过程

用户头像
叫练
关注
发布于: 21 小时前
Lamda(拉姆达)表达式演化过程

简介

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 以上版本支持哦!

总结


好啦,今天我们就讲到这里,希望大家有疑问可以提问,欢迎和我交流。我是【公众号:叫练,边叫边练;喜欢的可以加关注哦!再次感谢大家的观看支持。


发布于: 21 小时前阅读数: 6
用户头像

叫练

关注

我是叫练,边叫边练 2020.06.11 加入

Java高级工程师,熟悉多线程,JVM

评论

发布
暂无评论
Lamda(拉姆达)表达式演化过程