关于jdk8中的函数式编程示例

2022-03-12  本文已影响0人  天草二十六_简村人

一、问题描述

对比 filterEmployeesByAge()方法和 filterEmployeesBySalary 方法后,我们发现,大部分的方法体是相同的,只是 for 循环中对于条件的判断不同。
如果此时我们再来一个需求,查找当前公司中年龄小于或者等于 20 的员工信息,那我们又要创建一个过滤方法了。
看来使用常规方法是真的不方便啊!

1、员工类

@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
    private static final long serialVersionUID = -9079722457749166858L;
    private String name;
    private Integer age;
    private Double salary;
}

2、过滤年龄大于30岁的员工

public List<Employee> filterEmployeesByAge(List<Employee> list){
    List<Employee> employees = new ArrayList<>();
    for(Employee e : list){
        if(e.getAge() >= 30){
            employees.add(e);
        }
    }
    return employees;
}

3、过滤工资超过5000的员工

public List<Employee> filterEmployeesBySalary(List<Employee> list){
    List<Employee> employees = new ArrayList<>();
    for(Employee e : list){
        if(e.getSalary() >= 5000){
            employees.add(e);
        }
    }
    return employees;
}

二、问题解决

1、 先定义一个泛型接口 MyPredicate,对传递过来的数据进行过滤,符合规则返回 true,不符合规则返回 false。

public interface MyPredicate<T> {

    /**
     * 对传递过来的T类型的数据进行过滤
     * 符合规则返回true,不符合规则返回false
     */
    boolean filter(T t);
}

2、接下来,我们创建 MyPredicate 接口的实现类 FilterEmployeeByAge 来过滤年龄大于或者等于 30 的员工信息。

public class FilterEmployeeByAge implements MyPredicate<Employee> {
    @Override
    public boolean filter(Employee employee) {
        return employee.getAge() >= 30;
    }
}

3、我们继续获取当前公司中工资大于或者等于 5000 的员工信息,此时,我们只需要创建一个 FilterEmployeeBySalary 类实现 MyPredicate 接口,如下所示:

public class FilterEmployeeBySalary implements MyPredicate<Employee>{
    @Override
    public boolean filter(Employee employee) {
        return employee.getSalary() >= 5000;
    }
}

4、定义一个过滤员工信息的方法

//此时传递的参数不仅有员工的信息集合,同时还有一个我们定义的接口实例,在遍历员工集合时将符合过滤条件的员工信息返回

public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> myPredicate){
    List<Employee> employees = new ArrayList<>();
    for(Employee e : list){
        if(myPredicate.filter(e)){
            employees.add(e);
        }
    }
    return employees;
}

5、测试

@Test
public void test4(){
    List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeByAge());
    for (Employee e : employeeList){
        System.out.println(e);
    }
}


@Test
public void test5(){
    List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeBySalary());
    for (Employee e : employeeList){
        System.out.println(e);
    }
}

或者使用匿名内部类实现:

@Test
public void test6(){
    List<Employee> employeeList = this.filterEmployee(this.employees, new MyPredicate<Employee>() {
        @Override
        public boolean filter(Employee employee) {
            return employee.getAge() >= 30;
        }
    });
    for (Employee e : employeeList){
        System.out.println(e);
    }
}

@Test
public void test7(){
    List<Employee> employeeList = this.filterEmployee(this.employees, new MyPredicate<Employee>() {
        @Override
        public boolean filter(Employee employee) {
            return employee.getSalary() >= 5000;
        }
    });
    for (Employee e : employeeList){
        System.out.println(e);
    }
}


或者使用Lambda表达式

@Test
public void test8(){
    filterEmployee(this.employees, (e) -> e.getAge() >= 30).forEach(System.out::println);
}


@Test
public void test9(){
    filterEmployee(this.employees, (e) -> e.getSalary() >= 5000).forEach(System.out::println);
}

再或者使用 Lambda 表达式结合 Stream API,只要给出相应的集合,我们就可以完成对集合的各种过滤并输出结果信息。

@Test
public void test10(){
    employees.stream().filter((e) -> e.getSalary() >= 5000).forEach(System.out::println);
}

@Test
public void test11(){
    employees.stream().filter((e) -> e.getSalary() >= 5000).limit(2).forEach(System.out::println);
}

@Test
public void test12(){
    employees.stream().filter((e) -> e.getSalary() >= 5000).map(Employee::getName).forEach(System.out::println);
}

三、转载自infoq的写作平台文章的说明

7.3万字肝爆Java8新特性,我不信你能看完!(建议收藏)
原文链接: https://xie.infoq.cn/article/0b0da8f001cfe62f49e3c9da5

上一篇 下一篇

猜你喜欢

热点阅读