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

时间:2016-05-06 06:16:33

标签: stream java-8

我需要根据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());
}

这是一种正确的方法吗?

注意:以上代码工作正常我只是在寻找另一种更好的方法(如果有的话)。

案例1: getFilterList(null,null)返回所有员工的列表

案例2: getFilterList("abc",null)返回名字为abc的所有员工的名单。

5 个答案:

答案 0 :(得分:2)

根据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 :(得分: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。最后返回truefalsefilter决定是否应选择emp对象。

注意Stream<Predicate<Employee>> predicateStream中的每个Employee对象创建了empStream,这可能涉及一些开销。

答案 2 :(得分:0)

请注意,第二个条件需要预先指定第一个条件,如果firstNamelastName都是null,则返回Employee的列表。因此,即使不需要评估,也会评估您提出的许多条件。我会按照以下几点做到这一点:

return firstName == null && lastName == null ? 
                empList : 
                (lastName != null ? 
                        empList.stream().filter(emp -> emp.lastname.equals(lastName) :
                        empList.stream().filter(emp -> empfirstName.equals(firstName))
                ).colector(Collectors.toList());

答案 3 :(得分: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());

答案 4 :(得分: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());

使用ternery操作来应用过滤器(如果没有,在我的情况下只设置为true)