首页 > 解决方案 > 如何在Java中按多个字段过滤对象列表?

问题描述

我想按多个字段过滤对象列表,但用于过滤的这些字段可以更改。例如;

假设我们有一个具有一些属性的 Employee 类:

@Data
public class Employee {
   private Integer id;
   private Integer age;
   private String gender;
   private String firstName;
   private String lastName;

}

编写有时按年​​龄和性别或有时仅按名字过滤的方法的最佳方法是什么?(可以复制样本,即对于这个例子,它有 5 个属性,所以有 5!= 120 种可能性)它可以使用 lambda 或 Java 中的其他东西进行编码吗?

PS:任何可能性都没有预定义。无论请求来自什么,它都应该被它过滤。我相信下面的例子会让这个问题更清楚:

假设我们有一个与 Employee 具有相同属性的 Filter 对象。如果给定了年龄而其他为空,则此服务将仅按年龄过滤。或者只给出性别和名字,它应该按标准获得员工。

标签: javagenericslambdafilter

解决方案


您可以为每个属性实现某些搜索功能,例如

  • 对于年龄,可能的过滤器'Equal''Greater than''Less than'

  • 对于姓氏过滤器'is equal''begins with''ends with'.

  • 对于性别'is male'

您可以在 Employee 类中添加如下内容:

public static Predicate<Employee> ageEQ(int a) {
    return e -> e.getAge() == a;
}
public static Predicate<Employee> ageGT(int a) {
    return e -> e.getAge() > a;
}
public static Predicate<Employee> ageLT(int a) {
    return e -> e.getAge() < a;
}
public static Predicate<Employee> isMale() {
    return e -> e.getGender().equals("M");
}
public static Predicate<Employee> lastNameEQ(String name) {
    return e -> e.getLastName().equals(name);
}
public static Predicate<Employee> lastNameStartsWith(String name) {
    return e -> e.getLastName().startsWith(name);
}

并列出员工名单:

List<Employee> list = new ArrayList<>();
    list.add(new Employee(1,22,"M","Aaa","Bar"));
    list.add(new Employee(2,33,"F","Ccc","Ddd"));
    list.add(new Employee(3,44,"M","Eee","Fff"));
    list.add(new Employee(4,55,"F","Ggg","Hhh"));
    list.add(new Employee(5,66,"F","Mmm","Nnn"));

例如,过滤所有 40 岁以上的女性员工:

list.stream()
    .filter(Employee.ageGT(40).and(Employee.isMale().negate()))
    .forEach(System.out::println);

假设您的请求类似于 ?age>40&male=false ...


推荐阅读