原创

JAVA8系列教程-谓词过滤器

温馨提示:
本文最后更新于 2020年04月21日,已超过 1,675 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

在数学中,谓词通常被理解为布尔值函数 'P: X? {true, false}',称为X上的谓词。它可以被认为是操作员或函数返回一个值,该值是任一truefalse

Java 8谓词用法

在Java 8中,谓词功能接口,因此可以用作lambda表达式或方法引用的分配目标因此,在您认为的地方,我们可以在日常编程中使用这些true / false返回函数吗?我会说,您可以在需要评估类似对象的组/集合上的条件的任何地方使用谓词,以便评估可以得出true或false。

例如,您可以在这些实时用例中使用prdicates

  1. 查找在特定日期之后出生的所有孩子
  2. 披萨定下特定时间
  3. 员工超过一定年龄等

因此,java谓词似乎是一件有趣的事情。让我们更深入。

如我所说,Predicate功能接口这意味着我们可以在需要谓词的任何地方传递lambda表达式。例如,一种这样的方法是filter()来自Stream接口的方法

/**
 * 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);

我们可以将流假定为一种机制,以创建支持顺序和并行聚合操作的元素序列。这意味着我们可以随时通过一次调用收集并执行流中存在的所有元素的某些操作。

因此,从本质上讲,我们可以使用流和谓词来–

  • 首先从组中过滤某些元素,然后
  • 然后对过滤后的元素执行一些操作。

在集合上使用谓词

为了演示,我们有一个Employee如下类:

Employee.java
package predicateExample;
 
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
 
   //To change body of generated methods, choose Tools | Templates.
    @Override
    public String toString() {
        return this.id.toString()+" - "+this.age.toString();
    }
}

1.所有年龄在21岁以上的男性员工

public static Predicate<Employee> isAdultMale()
{
    return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M");
}

2.所有女性且年龄在18岁以上的员工

public static Predicate<Employee> isAdultFemale()
{
    return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F");
}

3.所有年龄超过给定年龄的员工

public static Predicate<Employee> isAgeMoreThan(Integer age)
{
    return p -> p.getAge() > age;
}

您可以在需要时构建更多它们。到现在为止还挺好。远远使用以上方法,我在EmployeePredicates.java中包括了以上3种方法

EmployeePredicates.java
package predicateExample;
 
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
 
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());
    }
}  

您会看到我创建了另一个实用程序方法filterEmployees()来显示java谓词filter基本上是使代码整洁并减少重复。您也可以编写多个谓词来构成谓词链,就像在构建器模式中所做的那样

因此,在此函数中,我们传递的列表,employees并传递一个谓词,然后此函数将返回employees满足参数谓词中提到的条件的新集合

TestEmployeePredicates.java
package predicateExample;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static predicateExample.EmployeePredicates.*;
 
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]

谓词在Java 8中确实是非常好的添加,只要有机会,我都会使用它。

关于Java 8中谓词的最终思考

  1. 他们将您的条件(有时是业务逻辑)转移到中心位置。这有助于分别对它们进行单元测试。
  2. 无需将任何更改复制到多个位置。Java谓词改善了代码维护。
  3. 与编写if-else块相比,例如“ filterEmployees(employees,isAdultFemale())”的代码可读性强。

好吧,这些是我在Java 8谓词中的想法。您如何看待此功能?在评论部分与我们所有人分享。

正文到此结束
本文目录