我有一个包含员工对象列表的人员列表。 员工具有姓名、年龄、部门、城市属性。 现在我有另一个列表的列表。 标准列表可以是动态的,因为它可以包含 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流进行比较和过滤?
有很多方法可以解决这个问题。我将使用独立的实现对
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());