根据某些条件添加过滤器 java 8

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

我需要根据 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的员工返回列表

stream java-8
5个回答
5
投票

根据

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));

就是这样:)


1
投票

你也可以这样做:

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
,这可能涉及一些开销。


0
投票

不确定这是否是最佳方式,但它摆脱了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());

0
投票

请注意,第二个条件优先于第一个条件,如果

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());

0
投票

在同样的事情上挣扎。对于任何寻找另一种方式的人:

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)

© www.soinside.com 2019 - 2024. All rights reserved.