我有一个要求,我必须根据多个动态过滤条件从列表中过滤对象。
我已经通过循环遍历对象编写代码,然后全部过滤并在任何条件不匹配时返回false。我写的代码是
Map<String, String> obj1 = new HashMap<>();
obj1.put("id", "1");
obj1.put("name", "name1");
obj1.put("dept", "IT");
obj1.put("sex", "M");
Map<String, String> obj2 = new HashMap<>();
obj2.put("id", "2");
obj2.put("name", "name2");
obj2.put("dept", "IT");
obj2.put("sex", "M");
Map<String, String> obj3 = new HashMap<>();
obj3.put("id", "3");
obj3.put("name", "name3");
obj3.put("dept", "DEV");
obj3.put("sex", "F");
ArrayList<Map<String, String>> employees = new ArrayList<>(Arrays.asList(obj1,obj2,obj3));
Map<String, String> filterCondition = new HashMap<>();
filterCondition.put("dept", "IT");
filterCondition.put("sex", "M");
List<Map<String, String>> filteredEmployee = new ArrayList<>();
for(Map<String,String> employee:employees){
if(isValid(filterCondition, employee)){
filteredEmployee.add(employee);
}
}
System.out.println(filteredEmployee);
isValid方法是
private static boolean isValid(Map<String, String> filterCondition, Map<String, String> employee) {
for(Entry<String, String> filterEntry:filterCondition.entrySet()){
if(!employee.get(filterEntry.getKey()).equals(filterEntry.getValue())){
return false;
}
}
return true;
}
如果我得到的过滤器是动态的,那么有没有更好的方法来实现它。
我已经在stackoverflow中看到了here的一些答案,但没有帮助
答案 0 :(得分:3)
将所有过滤器组合为单个谓词(使用stream,reduce和谓词组合):
Predicate<Map<String, String>> allConditions = filterCondition
.entrySet()
.stream()
.map(ThisClass::getAsPredicate)
.reduce((employee) -> true, Predicate::and);
然后只使用Stream.filter()
List<Map<String, String>> filteredEmployees = employees
.stream()
.filter(allConditions)
.collect(Collectors.toList());
辅助功能:
private static Predicate<Map<String, String>> getAsPredicate(Map.Entry<String, String> filter) {
return (Map<String, String> employee) -> employee.get(filter.getKey()).equals(filter.getValue());
}
答案 1 :(得分:2)
也许你可以在Stream中使用for循环:
Stream<Map<String, String>> employeeStream = employees.stream();
for (Map.Entry<String, String> entry : filterCondition.entrySet()) {
employeeStream = employeeStream.filter(map -> entry.getValue()
.equals(map.get(entry.getKey())));
}
List<Map<String, String>> filteredEmployee = employeeStream.collect(Collectors.toList());