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

Stream 根据java 8的某些条件添加过滤器,stream,java-8,Stream,Java 8,我需要根据一些参数筛选员工列表,如firstName、lastName等。这些参数是用户定义的。用户可以选择所有筛选器或筛选器的组合 public List<Employee> getFilterList(String firstName,String lastName) { List<Employee> empList = empRepository.getEmployees(); Stream<Employee> empStream=em

我需要根据一些参数筛选员工列表,如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());
}
public List getFilterList(String firstName,String lastName)
{
List employist=empRepository.getEmployees();
Stream 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))
}
返回empStream.collect(Collectors.toList());
}
这样做正确吗

注意:以上代码运行良好,我只是在寻找另一种更好的方法(如果有的话)

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


案例2:
getFilterList(“abc”,null)
返回所有名为abc的员工的列表。

您也可以这样做:

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());
List 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 predicateStream=predicateList.Stream();
返回predicateStream.map(predicate->predicate.test(emp)).reduce((a,b)->a&&b.get();
}).collect(Collectors.toList());
根据用户的选择,您需要通过添加谓词来创建
predicateList

predicateStream.map(predicate->predicate.test(emp))
返回一个
流。此流包含的值是在
emp
实例上应用谓词(即
predicate.test(emp)
)的结果。然后
reduce((a,b)->a和&b)
检查流中的所有结果是否为
true
。最后返回
true
false
,根据
filter
决定是否应选择
emp
对象


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

请注意,第二个条件优先于第一个条件,如果
firstName
lastName
都是
null
,返回
员工的列表。因此,您所放置的许多条件都会被计算,即使它们的计算不是必需的。我会按照以下思路来做:

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

它根据
firstName
过滤器的参数显示列表
empList
,或根据参数
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());

}

仅此而已:)

不确定这是否是最理想的方法,但它消除了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());
List 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());

在同样的事情上挣扎。对于任何正在寻找其他方法的人:

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)

在我看来没问题,您对此有问题吗?您是否关心大小写比较(即大写和小写)?不,我对该代码及其工作性能没有任何问题。但我不确定这种方法。@Sandeppebhardwaj补充了解释。代码在案例1中不起作用:
getFilterList(null,null)
,在这种情况下,它应该返回所有记录,案例2:
getFilterList(“abc”,null)
在这种情况下,所有emp的名字都是abc。正如我提到的,您需要根据用户的输入动态创建谓词,这里我刚刚向您展示了如何在对象列表上应用一个或多个条件。不要只使用我在
predicateList
中添加的谓词。这只是一个例子。@Sandeppebhardwaj根据您的具体需求更新了
predicateList
。它现在应该适用于这两种情况。仅当提供了
firstName
lastName
时,才会尝试执行筛选器吗?比如说,总共10条记录
firstName
存在并过滤5条记录
lastName
过滤器不存在-现在,是否尝试使用
lastName
过滤其余5条记录?(即是否会重复或访问5条还押记录中的每一条?)
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());