我需要根据 firstName 、 lastName 等参数过滤员工列表。这些参数是用户定义的,用户可以选择所有过滤器或过滤器组合。
public List<Employee> getFilterList(String firstName,String lastName)
{
List<Employee> empList = empRepository.getEmployees();
Stream<Employee> empStream=empList.stream();
if(firstName!=null)
{
empStream= empStream.filter(e-> e.getFirstname().equals(firstName))
}
if(lastName!=null)
{
empStream= empStream.filter(e-> e.getlastName().equals(lastName))
}
return empStream.collect(Collectors.toList());
}
这样做正确吗?
注意: 上面的代码工作正常我只是在寻找另一种更好的方法(如果有的话)。
案例一:
getFilterList(null,null)
所有员工的返回列表
案例2:
getFilterList("abc",null)
所有名字为abc的员工返回列表
根据
empList
过滤器的参数显示列表firstName
或根据参数lastName
过滤,代码模式几乎相同。所以我想出了下面的代码。
public List<Employee> getFilterList(String firstName,String lastName){
List<Employee> empList = empRepository.getEmployees();
return empList.stream().filter(getPredicateBiFun.apply(firstName,Employee::getFirstName))
.filter(getPredicateBiFun.apply(lastName,Employee::getLastName))
.collect(Collectors.toList());
}
看起来更像Java8风格。而这里有一个静态属性
getPredicateBiFun
你看可以根据参数得到对应的Predicate<Employee>
表达式。所以这只是一个BiFunction
和我们想要的一个很好的模式。
private static BiFunction<String, Function<Employee, String>, Predicate<Employee>> getPredicateBiFun = (name, getNameFun) -> employee -> name == null ? true : name.equals(getNameFun.apply(employee));
就是这样:)
你也可以这样做:
List<Predicate<Employee>> predicateList = new ArrayList<>();
predicateList.add(emp -> firstName == null || (emp.firstName != null && emp.firstName.equals(firstName)));
predicateList.add(emp -> lastName == null || (emp.lastName != null && emp.lastName.equals(lastName)));
empStream.filter(emp -> {
Stream<Predicate<Employee>> predicateStream = predicateList.stream();
return predicateStream.map(predicate -> predicate.test(emp)).reduce((a, b) -> a && b).get();
}).collect(Collectors.toList());
根据用户的选择,需要通过添加谓词来创建
predicateList
predicateStream.map(predicate -> predicate.test(emp))
返回 Stream<Boolean>
。该流包含在 predicate.test(emp)
实例上应用谓词(即 emp
)的结果值。然后reduce((a, b) -> a && b)
检查流中的所有结果是否都是true
。最后返回true
或false
,filter
据此决定是否选择一个emp
对象。
注意为
Stream<Predicate<Employee>> predicateStream
中的每个Employee
对象创建empStream
,这可能涉及一些开销。
不确定这是否是最佳方式,但它摆脱了ifs:
List<Employee> empList = empRepository.getEmployees();
return empList.stream()
.filter(e -> firstName == null || e.getFirstname().equals(firstName))
.filter(e -> lastName == null || e.getlastName().equals(lastName))
.collect(Collectors.toList());
请注意,第二个条件优先于第一个条件,如果
firstName
和lastName
都是null
,则返回Employee
的列表。因此,即使不需要对它们进行评估,也会对您提出的许多条件进行评估。我会按照以下几行做到这一点:
return firstName == null && lastName == null ?
empList :
(lastName != null ?
empList.stream().filter(emp -> emp.lastname.equals(lastName) :
empList.stream().filter(emp -> emp.firstName.equals(firstName))
).collect(Collectors.toList());
在同样的事情上挣扎。对于任何寻找另一种方式的人:
empList.stream()
.filter(firstName != null ? e -> e.getFirstName().equals(firstName) : e -> true)
.filter(lastName != null ? e -> e.getLastName().equals(lastName) : e -> true)
.collect(Collectors.toList());
使用三元运算是否应用过滤器(如果不是,在我的例子中设置为true)