美文网首页Java 8
Java 8 | Predicate

Java 8 | Predicate

作者: 懒癌正患者 | 来源:发表于2018-04-22 15:56 被阅读30次

    Predicate 是“断言”的意思。就是给你一段描述,判断这段描述是正确的还是错误的。这就像我们考试中做的判断题一样。

    在编程中,我们经常会有这样的操作。当我们有一个集合,我们需要筛选出符合我们要求的一部分,抛弃不符合的那部分。

    详细的例子就是,当我们拿到一份学成成绩单,我们需要获取那些60分以上的学生名单。

    List<Integer> scores = Arrays.asList(40, 55, 59 , 69, 80);
    List<Integer> passing = new ArrayList();
    
    for (Integer score : scores) {
      if (score >= 60) {
        passing.add(score);
      }
    }
    

    但是 Java 8 带来了 Lambda 表达式,我们现在完成这个功能只需要一行代码

    List<Integer> passing  = scores.stream().filter((score) -> score >= 60).collect(Collectors.toList());
    

    其中 filter 方法中接受的参数就是 PredicatePredicate 在 lambda 表达式中作为判断条件很是常用,下面我们来深入了解一下 Predicate

    首先 Predicate 是一个函数式接口,这就意味着 Predicate 可以用一个 Lambda 表达式来表示。正如上面 filter() 方法传递的那样。

    /**
     * Returns a stream consisting of the elements of this stream that match
     * the given predicate.
     *
     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
     * operation</a>.
     *
     * @param predicate a non-interfering stateless predicate to apply to each element to determine if it
     * should be included in the new returned stream.
     * @return the new stream
     */
    Stream<T> filter(Predicate<? super T> predicate);
    

    Streams 我们后面再介绍,这里我们可以把它当做是一个“集合”,我们可以对这个“集合”做某些操作。让我们看看一些例子。

    在集合中使用 Predicate

    定义一个 Employee

    public class Employee {
        
       public Employee(Integer id, Integer age, String gender, String fName, String lName){
           this.id = id;
           this.age = age;
           this.gender = gender;
           this.firstName = fName;
           this.lastName = lName;
       }
         
       private Integer id;
       private Integer age;
       private String gender;
       private String firstName;
       private String lastName;
     
       //Please generate Getter and Setters
     
        @Override
        public String toString() {
            return this.id.toString()+" - "+this.age.toString(); //To change body of generated methods, choose Tools | Templates.
        }
    }
    
    1. 年龄大于21的男性员工
    public static Predicate<Employee> isAdultMale() {
        return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M");
    }
    
    1. 年龄大于 18 的女性员工
    public static Predicate<Employee> isAdultFemale() {
        return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F");
    }
    
    1. 年龄大于指定年龄的员工
    public static Predicate<Employee> isAgeMoreThan(Integer age) {
        return p -> p.getAge() > age;
    }
    

    我们可以具体的过滤条件条件常见不同的 Predicate。

    public class EmployeePredicates {
        public static Predicate<Employee> isAdultMale() {
            return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M");
        }
         
        public static Predicate<Employee> isAdultFemale() {
            return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F");
        }
         
        public static Predicate<Employee> isAgeMoreThan(Integer age) {
            return p -> p.getAge() > age;
        }
         
        public static List<Employee> filterEmployees (List<Employee> employees, Predicate<Employee> predicate) {
            return employees.stream().filter( predicate ).collect(Collectors.<Employee>toList());
        }
    }  
    

    这样使得我们的代码更加简洁

    public class TestEmployeePredicates {
        public static void main(String[] args){
            Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
            Employee e2 = new Employee(2,13,"F","Martina","Hengis");
            Employee e3 = new Employee(3,43,"M","Ricky","Martin");
            Employee e4 = new Employee(4,26,"M","Jon","Lowman");
            Employee e5 = new Employee(5,19,"F","Cristine","Maria");
            Employee e6 = new Employee(6,15,"M","David","Feezor");
            Employee e7 = new Employee(7,68,"F","Melissa","Roy");
            Employee e8 = new Employee(8,79,"M","Alex","Gussin");
            Employee e9 = new Employee(9,15,"F","Neetu","Singh");
            Employee e10 = new Employee(10,45,"M","Naveen","Jain");
             
            List<Employee> employees = new ArrayList<Employee>();
            employees.addAll(Arrays.asList(new Employee[]{e1,e2,e3,e4,e5,e6,e7,e8,e9,e10}));
                    
            System.out.println(filterEmployees(employees, isAdultMale()));
             
            System.out.println(filterEmployees(employees, isAdultFemale()));
             
            System.out.println(filterEmployees(employees, isAgeMoreThan(35)));
             
            //Employees other than above collection of "isAgeMoreThan(35)" can be get using negate()
            System.out.println(filterEmployees(employees, isAgeMoreThan(35).negate()));
        }
    }
     
    Output:
     
    [1 - 23, 3 - 43, 4 - 26, 8 - 79, 10 - 45]
    [5 - 19, 7 - 68]
    [3 - 43, 7 - 68, 8 - 79, 10 - 45]
    [1 - 23, 2 - 13, 4 - 26, 5 - 19, 6 - 15, 9 - 15]
    

    关于 Predicate 的一些思考

    1. Predicate 使得将一些条件(或者业务逻辑)统一到一个地方进行管理,方便单元测试
    2. 统一管理是的修改也更加方便了
    3. 可读性更强了,filterEmployees(employees, isAdultFemale()) 更容易理解,而且不再是 if-else 的代码块了

    相关文章

      网友评论

        本文标题:Java 8 | Predicate

        本文链接:https://www.haomeiwen.com/subject/qthclftx.html