Java 8 -Lambda表达式(1)

为什么使用Lambda表达式?

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

接下来从代码上来看看Lambda 有什么好?

--下面先不是用lambda表达式

/**
 * 员工实体类
 *
 * @author Administrator
 * @version 1.0
 * @date 2019/11/6 10:54
 */
public class Employee {

    private Integer age;
    private String name;
    private Double salary;


        有参/无参构造器
        get/set方法
        toString
}

初始化员工类如下

    //初始化员工类集合
    static List<Employee> employees = Arrays.asList(
            new Employee("张三", 18, 3333.33),
            new Employee("李四", 28, 5555.55),
            new Employee("王五", 38, 6666.66),
            new Employee("赵柳", 48, 7777.77),
            new Employee("田七", 58, 8888.88)
    );

需求1: 查出年龄大于38的员工集合

实现如下

    //需求:查出年龄大于38的员工集合
    public List<Employee> filterEmployee() {
        List<Employee> employeeList = new ArrayList<>();
        for (Employee each : employees) {
            if (each.getAge() > 35) {
                employeeList.add(each);
            }
        }
        return employeeList;
    }
    
    @Test
    public void testEmployee(){
        System.out.println("-------需求1---------");
        List<Employee> employeeList = filterEmployee();
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
    }

有添加一个需求2:获取当前公司员工工资大于4500 的员工信息

    @Test
    public void testEmployee() {
        System.out.println("-------需求1---------");
        List<Employee> employeeList = filterEmployee();
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
        System.out.println("--------需求2------------");
        List<Employee> employees1 = filterEmployee1();
        for (Employee employee : employees1) {
            System.out.println(employee);
        }
    }

    //需求2:获取当前公司员工工资大于4500 的员工信息
    public List<Employee> filterEmployee1() {
        List<Employee> employeeList = new ArrayList<>();
        for (Employee each : employees) {
            if (each.getSalary() > 4500) {
                employeeList.add(each);
            }
        }
        return employeeList;
    }

运行结果如下

从需求1到需求2再到等等需求

  • 改变的就是each.getAget() 和 each.getSalary()方法,剩下的代码都没有进行改变,比如说我们现在有一个需求查出员工年龄小于35岁的员工,这样我们就可以复制 filterEmployee()这个方法 ,唯一改变的就是把里面大于改为小于,这样代码就冗余了。
  • 对代码最好的优化方式,不是把公共的代码提取出来,而是设计模式。

优化方式1

创建策略模式员工条件接口

public interface MyPredicate<T> {

    public boolean test(T t);

}

创建实现类实现于 MyPredicate ,如根据年龄查询

public class FilterEmployeeByAge implements MyPredicate<Employee> {

    @Override
    public boolean test(Employee employee) {
        return employee.getAge() > 35;
    }
}

接下来就是方法实现如下-->查出年龄大于35的员工信息

    //优化方式1
    public List<Employee> filterEmployee2(MyPredicate<Employee> myPredicate) {
        List<Employee> emps = new ArrayList<>();
        for (Employee emp : employees) {
            if (myPredicate.test(emp)) {
                emps.add(emp);
            }
        }
        return emps;
    }

    @Test
    public void test02(){
        List<Employee> employeeList = filterEmployee2(new FilterEmployeeByAge());
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
    }

如果要实现需求2,直接写一个根据工资查询的接口就可以了-->需求:查出工资大于4500的员工信息

public class FilterEmployeeBySalary implements MyPredicate<Employee> {
    @Override
    public boolean test(Employee e) {
        return e.getSalary() > 4500;
    }
}

在方法实现中直接可以共用方法 filterEmployee2(MyPredicate<Employee> myPredicate) 传入不同的策略模式,从而查询出不同的员工集合,如下

    @Test
    public void test02(){
        System.out.println("-----优化后需求1-----");
        List<Employee> employeeList = filterEmployee2(new FilterEmployeeByAge());
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
        System.out.println("-----优化后需求2-----");
        List<Employee> employees = filterEmployee2(new FilterEmployeeBySalary());
        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }

结果如下

  • 比如说你以后添加不同的判断规则,直接通过写不同的实现类,然后传入判断规则,使用公共的查询方法,就可以查出员工集合
  • 缺点,每次实现类的方法写了很少的内容,需要单独的创建一个类,这个类的创建是很多余的,优化方法2,参考下面

优化方法2-匿名内部类

    //优化方法2 -匿名内部类
    @Test
    public void test03(){
        System.out.println("--------优化2-查出大于35的员工信息----------------");
        List<Employee> employees = filterEmployee2(new MyPredicate<Employee>() {
            @Override
            public boolean test(Employee employee) {
                return employee.getAge() > 35;
            }
        });
        for (Employee employee : employees) {
            System.out.println(employee);
        }
        System.out.println("--------优化2-查出员工工资大于4500的员工信息-----------");
        List<Employee> employeeList = filterEmployee2(new MyPredicate<Employee>() {
            @Override
            public boolean test(Employee employee) {
                return employee.getSalary() > 4500;
            }
        });
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
    }
  • 不知道你有没有发现,匿名内部类其实还是可以优化的,需求1与需求2 有用的代码只有一句
    employee.getAge() > 35  和 employee.getSalary() > 4500     代码还是不够简洁,代码可读性比较差

运行结果如下

代码优化方法3-lambda表达式

    //优化方法3-lambda
    @Test
    public void test04(){
        System.out.println("-------优化3-查出大于35的员工信息--------");
        List<Employee> employees = filterEmployee2(employee -> employee.getAge() > 35);
        employees.forEach(System.out::println);
        System.out.println("-------优化3-查出员工工资大于4500的员工信息--------");
        List<Employee> employeeList = filterEmployee2(employee -> employee.getSalary() > 4500);
        employeeList.forEach(System.out::println);
    }

结果为

如果对上面的表达式还不满意还有优化方式4,如下

优化方式4-stream api

    //优化4 --stream api
    @Test
    public void test05(){
        System.out.println("-------优化4-查出大于35的员工信息--------");
        employees.stream()
                .filter(e->e.getAge()>35)
                .forEach(System.out::println);
        System.out.println("-------优化4-查出员工工资大于4500的员工信息--------");
        employees.stream()
                .filter(e->e.getSalary()>4500)
                .forEach(System.out::println);
        System.out.println("-------优化4-查出员工工资大于4500的员工信息只取出前俩个--------");
        employees.stream()
                .filter(e->e.getSalary()>4500)
                .limit(2)
                .forEach(System.out::println);
        System.out.println("-------优化4-取出员工集合中所有员工的名字--------");
        employees.stream()
                .map(Employee::getName)
                .forEach(System.out::println);
    }

结果如下

所以说以后再开发中,尽量使用lambda表达式,来提高代码的可读性

发布了256 篇原创文章 · 获赞 188 · 访问量 65万+

猜你喜欢

转载自blog.csdn.net/qq_40646143/article/details/102930879