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

标签 java lambda java-8 java-stream

我有一个实体 Employee

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

现在我有了这些员工的名单。我想过滤掉那些 name = null 并设置 addr = 'A' 的对象。我能够实现如下所示:

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

现在list2将包含所有姓名不为空的员工,然后将这些员工的addr设置为A。 我还想找到那些被过滤的员工(name == null)并将它们保存在数据库中。我实现的一种方法如下:

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 表达式中执行此操作,而不是编写单独的方法吗?

最佳答案

一般来说,您不应该在行为参数中使用副作用。请参阅 “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 表达式中写入太多代码,因为您当然无法直接调用该代码来创建测试用例。但这是编程风格的问题,而不是技术限制。

关于java - 在java中使用lambdas从流中获取过滤记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41261674/

相关文章:

java - 如何使用 Xuggle 从相机/网络摄像头捕获视频和音频?

java - Gson:java.lang.StackOverflowError: null

c++ - 什么时候通过引用在另一个 lambda 中捕获一个 lambda 是安全的?

java - 从命令行运行时http连接超时

java - 通用链表的并行排序

java - Tomcat v8+Servlet v3.1 在运行 servlet 时出现 404 错误

java - Docker OpenJDK -Xmx 或

c# - PropertyExpression 丢失

c++ - 这个似乎链接 lambda 的 C++14 结构叫什么?

java - 如何在静态导入上使用方法引用?