使用java流基于动态标准过滤列表

问题描述 投票:0回答:1

我有一个包含员工对象列表的人员列表。 员工具有姓名、年龄、部门、城市属性。 现在我有另一个列表的列表。 标准列表可以是动态的,因为它可以包含 1 个或多个标准。我想根据这个动态标准列表过滤员工列表,因此如果类型是年龄,那么我需要将年龄与 emp.age 进行比较,如果类型是城市,那么我需要与 emp.city 进行比较。 我在这里不包括 getter/setter。但这些类是这样的:

public class Person {

    private List<Employee> empList;

    public Person(List<Employee> empList) {
        super();
        this.empList = empList;
    }

    public List<Employee> getEmpList() {
        return empList;
    }

    public void setEmpList(List<Employee> empList) {
        this.empList = empList;
    }

}
public class Employee {
    
    private String name;
    private int age;
    private String city;
    private String dept;
    
    public Employee(String name, int age, String city, String dept) {
        super();
        this.name = name;
        this.age = age;
        this.city = city;
        this.dept = dept;
    }
}

public class Criteria {
    
    private CriteriaType type;
    private String value;
    
    public Criteria(CriteriaType type, String value) {
        super();
        this.type = type;
        this.value = value;
    }
}
public enum CriteriaType {  
    NAME, CITY, AGE, DEPT
}

public class FilterEmployee {

    public static void main(String[] args) {
        
        Employee emp1 = new Employee("John", 30, "Dallas", "HR");
        Employee emp2 = new Employee("Steve", 31, "Austin", "HR");
        Employee emp3 = new Employee("Andrew", 25, "Houston", "Finance");
        Employee emp4 = new Employee("Mike", 30, "Dallas", "HR");
        
        List<Employee> empList = new ArrayList<Employee>();
        empList.add(emp1);
        empList.add(emp2);
        empList.add(emp3);
        empList.add(emp4);
        
        Person personObj = new Person(empList);
        
        Criteria c1 = new Criteria(CriteriaType.CITY, "Dallas");
        Criteria c2 = new Criteria(CriteriaType.NAME, "Mike");
        
        
        List<Criteria> criteriaList = new ArrayList<Criteria>();
        criteriaList.add(c1);
        criteriaList.add(c2);
        
        //Filter person list containing employee list on the basis of //Criteria list
        
        

    }

}

有没有一种干净的方法来使用java流进行比较和过滤?

java java-stream
1个回答
0
投票

有很多方法可以解决这个问题。我将使用独立的实现对

if/else
进行子类化,而不是与外部
switch
Criteria
块配对来应用逻辑,而不是枚举:

public abstract class Criteria<T> implements Predicate<Person> {
    protected final T value;

    public Criteria(T value) {
        this.value = value;
    }
}

public class NameCriteria extends Criteria<String> {
    public NameCriteria(String name) {
        super(name);
    }

    @Override
    protected boolean test(Person person) {
        return person.getName().equals(this.value);
    }
}

public class AgeCriteria extends Criteria<Integer> {
    public AgeCriteria(int age) {
        super(age);
    }

    @Override
    protected boolean test(Person person) {
        return person.getAge() == this.age;
    }
}

...等等。

由于我们正在实现

Predicate
类,因此我们可以使用
and()
方法来合并它们,如下所示:

List<Criteria<?>> criteriaList = Arrays.asList(
        new CityCriteria("Dallas"),
        new NameCriteria("Mike"));

Predicate<Person> combinedFilter = criteriaList.stream()
        .reduce(Predicate::and)
        .orElse(() -> true);

然后这是针对您的列表的简单过滤操作:

List<Employee> filtered = empList.stream()
        .filter(combinedFilter)
        .collect(Collectors.toList());
© www.soinside.com 2019 - 2024. All rights reserved.