java - 为什么 java 收集流对每个 getter 运行两次?

标签 java performance java-8 java-stream collectors

我有一个包含项目的列表,其中每个项目都是一个具有我感兴趣的 getter 方法的对象。我想遍历整个列表以总结所有这些 getter 结果。

当我使用 java 8 流时,它看起来像这样:

double currentProduction = itemList.stream().collect(
    Collectors.summingDouble((e) -> e.getProduction(param)));

在普通的旧 java 中,它看起来像这样:

for (Item item : itemList) {
    currentProduction += item.getProduction(param);
}

这两种方法产生完全相同的结果,但我的记录器报告说,对于每个项目实例,getProduction() 方法在 java 8 流解决方案的情况下运行两次。在普通的旧 java 列表迭代解决方案中,getProduction 方法仅按预期在每个实例中运行一次。

由于 getProduction 方法的成本很高,这对我来说是个问题。

这是为什么?我能做些什么(除了只使用 for 循环)?

最佳答案

这是 Collectors.summingDouble 实现中的错误。

您可以改用 itemList.stream().mapToDouble(Class1::getProduction).sum()

错误详情:

Collector 实现的来源。

    return new CollectorImpl<>(
            () -> new double[3],
            (a, t) -> { sumWithCompensation(a, **mapper.applyAsDouble(t)**);
                        a[2] += **mapper.applyAsDouble(t)**;},
            (a, b) -> { sumWithCompensation(a, b[0]);
                        a[2] += b[2];
                        return sumWithCompensation(a, b[1]); },
            a -> computeFinalSum(a),
            CH_NOID);

错误由** 标记。他们调用 mapper.applyAsDouble(t) 两次。

关于java - 为什么 java 收集流对每个 getter 运行两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45238273/

相关文章:

java - 如何使用 JSch 库在 ec2 连接中将 .pem 文件内容用作字符串

c++ - 混合 cout 和 printf 以获得更快的输出

Java 调试接口(interface)、Lambda 和行号

java - 在新的 Android Studio 中找不到 UI 设计器

Java:如何循环三个List<String>

java - 如何在 Java 的枚举中保存图像?

python - 为什么多次调用小数据时 numpy.linalg.norm 变慢?

performance - 加速numpy矩阵逆

java - 在 java8 中过滤 Optional<List<Object>>

java - Metaspace 和 Native Area 内存是如何在 Java 中管理的?