使用java中的lambdas从流中获取过滤记录

时间:2016-12-21 11:24:10

标签: java lambda java-8 java-stream

我有一个实体员工

class Employee{
          private String name;
          private String addr;
          private String sal;
 }

现在我有这些员工的名单。我想过滤掉名称为null并设置addr ='A'的对象。我能够达到如下目标:

List<Employee> list2=    list.stream()
            .filter(l ->  l.getName() != null)
            .peek(l -> l.setAddr("A"))
            .collect(Collectors.toList());

现在list2将拥有名称不为null的所有员工,然后将addr设置为这些员工的A. 我还想找到的是那些被过滤的员工(名称== null)并将其保存在DB中。我实现的方式如下:

List<Employee> list2=    list.stream()
            .filter(l -> filter(l))
            .peek(l -> l.setAddr("A"))
            .collect(Collectors.toList());

private static boolean filter(Employee l){
    boolean j = l.getName() != null;
    if(!j)
          // save in db
    return j;
}

1)这是正确的方法吗?

2)我们可以直接在lambda表达式中执行此操作而不是编写单独的方法吗?

2 个答案:

答案 0 :(得分:4)

通常,您应该在行为参数中使用副作用。请参阅“Stateless behaviors” and “Side-effects” of the package documentation部分。此外,建议不要将peek用于非调试目的,请参阅“In Java streams is peek really only for debugging?”

尝试将所有这些不同的操作压缩到单个Stream管道中没有多大优势。考虑清洁的替代方案:

Map<Boolean,List<Employee>> m = list.stream()
    .collect(Collectors.partitioningBy(l -> l.getName() != null));
m.get(false).forEach(l -> {
    // save in db
});
List<Employee> list2 = m.get(true);
list2.forEach(l -> l.setAddr("A"));

关于你的第二个问题,一个lambda表达式允许几乎所有东西,一个方法。不同之处在于声明,即您不能声明其他类型参数也不能注释返回类型。但是,您应该避免在lambda表达式中编写太多代码,因为当然,您无法创建直接调用该代码的测试用例。但这是编程风格的问题,而不是技术限制。

答案 1 :(得分:0)

如果你可以使用peek来实现你的逻辑(虽然不建议除非学习),你可以做以下事情:

List<Employee> list2=    list.stream()
        .peek(l -> { // add this peek to do persistence
              if(l.getName()==null){
                  persistInDB(l);
              }
        }).filter(l ->  l.getName() != null)
        .peek(l -> l.setAddr("A"))
        .collect(Collectors.toList());

您也可以这样做:

    List<Employee> list2 =    list.stream()
              .filter(l->{
                  boolean condition = l.getName()!=null;
                  if(condition){
                      l.setAddr("A");
                  } else {
                      persistInDB(l);
                  }
                  return condition;
              })
              .collect(Collectors.toList());

希望这有帮助!