细说为什么要使用Lambda表达式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/oXinYangonly/article/details/81369874

Lambda表达式

  • Lambda是一个匿名函数,可以理解为一段可以传递的代码,将代码像数据一样进行传递,可以写出更加简介、更加灵活的代码。作为一宗更紧凑的代码风格,使Java的语言表达能力得到了提升

下面我们使用匿名内部类的方式创建一个线程

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("run ... ");
    }
};

Thread thread = new Thread(runnable);
thread.start();

在上面的代码中,我们使用了Runnable接口直接创建了一个对象,用了6行代码,但是在这6行代码中,真正有用的代码只有run方法中的一行

System.out.println("run ... ");

接下来我们使用Lambda表达式来简化这些代码

Runnable runnable = ()-> System.out.println("run ...");
Thread thread = new Thread(runnable);
thread.start();

此时,我们的代码就只有三行了,但是这并不是最终的版本,请看下面的代码

new Thread(()->System.out.println("run ... ")).start();

我们使用了最少的代码量,实现了同样的功能

Lambda表达式范例

需求:对教务系统中的学生进行查询操作

  • 创建一个学生类,属性分别有姓名,性别,年级
public class Student {
    /**
     * 姓名
     */
    private String name;
    /**
     * 性别
     * 男 1
     * 女 0
     */
    private int gender;
    /**
     * 年级
     * 1 一年级
     * 2 二年级
     * 3 三年级
     * 4 四年级
     */
    private int grade;

}
  • 需求一:获取学生中三年级及以上的学生

代码思路,将上述的学生集合作为参数,传入一个过滤的方法中,然后返回符合条件的学生集合

public List<Student> filterStudentsByGrade(List<Student> students){、

    List<Student> stus = new ArrayList<>();
    for (Student s : students){
        if(s.getGrade() >= 3){
            stus.add(s);
        }
    }
    return stus;
}

此时,我们就完美的实现了需求中所要的功能!

但是,日常开发中程序员最痛恨的事情发生了,需求改了

  • 需求二:获取学生中的男同学

思路:最简单的方式,我们写一个新的方法

public List<Student> filterStudentsByGender(List<Student> students){
    List<Student> stus = new ArrayList<>();
    for (Student s : students){
        if(s.getGender() == 1){
            stus.add(s);
        }
    }
    return stus;
}

可是,这样的需求越来越多的时候,我们发现,代码中的方法千篇一律,每个方法中只有判断的条件不一样,其他的代码都是一样的,大量的冗余代码,要求我们必须要对代码进行优化、重构

无数的前辈们在趟过了无数的坑之后,为我们总结出来了非常好的优化代码的东西————设计模式

接下来,我们使用设计模式对上面的代码进行优化

  • 创建一个简单策略接口SimpleStrategy,其中的方法operate中可以传入一个对象,然后就可以在这个接口的实现类中,进行过滤条件处理
public interface SimpleStrategy<T>{

    public boolean operate(T t);
}
  • 这样我们就可以用一个全新的方法,去替换之前那些因为不断增加的需求而写的千篇一律的方法
public List<Student> filterStudentByStrategy(List<Student> students,SimpleStrategy<Student> strategy){
    List<Student> stus = new ArrayList<>();
    for (Student s : students){
        if(strategy.operate(s)){
            stus.add(s);
        }
    }
    return stus;
}

此时,我们看到只需要在方法中传一个SimpleStrategy的一个实现类,就能自由的进行过滤了,测试代码如下:

@Test
public void getMoreThanThreeGrade(){
   List<Student> sts =  filterStudentByStrategy(students, new SimpleStrategy<Student>() {
        @Override
        public boolean operate(Student student) {
            return student.getGender() == 1;
        }
    });
}

虽然我们使用了策略模式,并通过匿名内部类的方式对学生信息进行了过滤,可是在整个的代码,真正有用的代码其实就一句

student.getGender() == 1;

可是我们为了完成功能,却又不得不写那些重复冗余的代码

  • 福音:使用Lambda表达式,不在写重复冗余的代码
List<Student> sts =  filterStudentByStrategy(students,(s)->s.getGender() == 1);

此时,我们最后的过滤代码就只有一行了,但是真的就完美了吗?未必!!!

我们在上面还创建了一个策略的接口呢,而且还声明了一个方法,代码还是很多,那么有没有什么方式,不创建接口,也不用声明一个过滤的方法,直接用一行代码就能实现上面的功能呢?

当然有,我们只需要使用Lambda表达式和Stream API就能完美的实现上述的功能了

List<Student> sts =  students.stream().filter(student -> student.getGender() == 1).collect(Collectors.toList());

这样就真正的完美了!!!

原文链接http://blog.3811811.com/2018/08/02/%E7%BB%86%E8%AF%B4%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%BF%E7%94%A8lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/

猜你喜欢

转载自blog.csdn.net/oXinYangonly/article/details/81369874