【问题标题】:why java stream "reduce()" accumulates the same object为什么java流“reduce()”会累积相同的对象
【发布时间】:2016-01-27 02:30:48
【问题描述】:
        ComparisonResults comparisonResults = requestsList
                .parallelStream()
                .map(item -> getResponse(item))
                .map(item -> compareToBl(item))
                .reduce(new ComparisonResults(), (result1, result2) ->
                {
                    result1.addSingleResult(result2);
                    return result1;
                });

什么时候

    private ComparisonResults compareToBl(CompleteRoutingResponseShort completeRoutingResponseShortFresh) {
...

        ComparisonResults comparisonResults = new ComparisonResults();
...
            return comparisonResults;
}

但是当我调试时:

 .reduce(new ComparisonResults(), (result1, result2) ->
                    {
                        result1.addSingleResult(result2);
                        return result1;
                    });

我看到 result1result2 总是同一个对象(对象 id 在 想法)

result1 等于 result2

【问题讨论】:

  • 为什么会有这样的问题?
  • 我想将不同的对象累积成一个对象。与自己不一样

标签: java multithreading concurrency java-stream reduce


【解决方案1】:

addSingleResult 应该返回一个新对象作为 this 的修改副本,因此您应该将代码更改为:

.reduce(new ComparisonResults(), (result1, result2) ->
                {
                    return result1.addSingleResult(result2);
                });

否则,您总是返回相同的实例(没有修改)。

来自Java documentation

reduce 操作总是返回一个新值。然而 累加器函数每次处理时也会返回一个新值 流的一个元素。假设你想减少元素 将流转换为更复杂的对象,例如集合。这有可能 阻碍您的应用程序的性能。如果你的减少操作 涉及将元素添加到集合中,然后每次您的 累加器函数处理一个元素,它创建一个新集合 包括元素,这是低效的。会更多 相反,您可以有效地更新现有集合。你可以做 这与 Stream.collect 方法一起使用,下一节将对此进行介绍。

【讨论】:

  • addSingleResult() 返回无效。我应该将其更改为非无效?
  • @EladBenda 是的,您应该返回一个包含聚合信息的新元素,以便使用 reduce。检查我的答案编辑。
  • @EladBenda 一般来说,您有两种减少序列的方法:(A)更新单个累积实例的状态[就像您最初尝试做的那样]。 (B) 对于初始序列的每个元素,返回一个新的累加器实例。要遵循 (A) 策略,您应该使用 collect 区域 reduce 对 (B) 有好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
  • 2022-09-23
  • 1970-01-01
  • 2019-07-30
  • 2020-06-05
  • 1970-01-01
相关资源
最近更新 更多