Java 8 | Predicate

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

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

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

List scores = Arrays.asList(40, 55, 59 , 69, 80);
List passing = new ArrayList();

for (Integer score : scores) {
  if (score >= 60) {
    passing.add(score);
  }
}

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

List 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.
 *
 * 

This is an intermediate * operation. * * @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 filter(Predicate 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 isAdultMale() {
    return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M");
}
  1. 年龄大于 18 的女性员工
public static Predicate isAdultFemale() {
    return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F");
}
  1. 年龄大于指定年龄的员工
public static Predicate isAgeMoreThan(Integer age) {
    return p -> p.getAge() > age;
}

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

public class EmployeePredicates {
    public static Predicate isAdultMale() {
        return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M");
    }
     
    public static Predicate isAdultFemale() {
        return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F");
    }
     
    public static Predicate isAgeMoreThan(Integer age) {
        return p -> p.getAge() > age;
    }
     
    public static List filterEmployees (List employees, Predicate predicate) {
        return employees.stream().filter( predicate ).collect(Collectors.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 employees = new ArrayList();
        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)