繁体   English   中英

Java 8 Stream:迭代,处理和计数

[英]Java 8 Stream: Iterating, Processing and Count

以这种方式处理和统计处理数据是否可以?

long count = userDao.findApprovedWithoutData().parallelStream().filter(u -> {
    Data d = dataDao.findInfoByEmail(u.getEmail());
    boolean ret = false;
    if (d != null) {
        String result = "";
        result += getFieldValue(d::getName, ". \n");
        result += getFieldValue(d::getOrganization, ". \n");
        result += getFieldValue(d::getAddress, ". \n");
        if(!result.isEmpty()) {
            u.setData(d.getInfo());
            userDao.update(u);
            ret = true;
        }
    }
    return ret;
}).count();

因此,简而言之:迭代不完整的记录,如果数据存在则更新并计算这些记录数?

恕我直言这是不好的代码,因为:

过滤谓词具有(非常显着的)副作用

谓词不应该有副作用(就像吸气剂不应该)。 这是意料之外的,这使它变得糟糕。

过滤谓词的效率非常低

每次执行谓词都会导致大量查询被触发,这使得此代码无法扩展。

乍一看,主要目的似乎是计数,但实际上这是一个小的(可有可无的)信息

好的代码使得它显而易见(与此代码不同)

您应该更改代码以使用(相当简单的)单个更新查询(使用连接)并从持久性API的结果中获取“更新的行数”信息的计数。

这取决于您对process的定义。 我不能给你一个明确的yes or no因为我认为很难在不理解你的代码及其实现方式的情况下得出结论。

您正在使用并行流,并且Java运行时会根据ForkJoinPool的公共池中的可用线程数将Stream拆分为子流。

使用并行性时,您需要注意可能的副作用:

  1. 干扰(流中的Lambda表达式不应干扰)

流操作中的Lambda表达式不应该干扰。 在流水线处理流时修改流的源时发生干扰。

  1. Statetful Lambda表达式

避免在流操作中使用有状态lambda表达式作为参数。 有状态lambda表达式的结果取决于在执行管道期间可能更改的任何状态。

查看您的问题并将上述要点应用于此。

非干扰 >强烈声明Lambda表达式在流水线操作期间不应干扰流源(除非流源是并发的),因为它可能导致:

  • 异常(即ConcurrentModificationException)
  • 错误答案
  • 不一致的行为

除了在中间操作(即过滤器)中进行修改的性能良好的流之外,请在此处阅读更多内容。

您的Lambda表达式确实会干扰流的来源,这是不建议的,但干扰是在中间操作中,现在一切都归结为流是否表现良好。 因此,在涉及干扰时,您可能会考虑重新考虑您的lambda表达式。 它也可能归结为您如何通过userDao.udpate更新流的来源,这在您的问题中并不清楚。

有状态Lambda表达式 >您的Lambda表达式似乎不是有状态的,这是因为Lambda的结果取决于在执行管道期间不会更改的值/ s。 所以这不适用于您的情况。

我建议你阅读Java 8 Stream的文档以及这个博客 ,它很好地解释了Java 8 Stream的例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM