首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java 8中的reduce累加器允许修改它的参数吗?

Java 8中的reduce累加器允许修改它的参数吗?
EN

Stack Overflow用户
提问于 2014-05-26 20:13:58
回答 2查看 5.6K关注 0票数 17

在Java 8中,Stream有一个方法reduce:

T reduce(T identity, BinaryOperator<T> accumulator);

是否允许累加器运算符修改其任何一个参数?我假设没有,因为JavaDoc说累加器应该是NonInterfering,尽管所有的例子都在讨论修改集合,而不是修改集合的元素。

所以,举个具体的例子,如果我们有

 integers.reduce(0, Integer::sum);

假设Integer是可变的,sum会被允许修改它的第一个参数,将它的第二个参数的值添加(就地)吗?

我想不会,但我也想要一个这种干扰导致问题的例子。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-26 20:58:27

不是的。累加器不应该修改它的参数;它接受两个值并产生一个新值。如果您想在累积过程中使用突变(例如,将字符串累积到StringBuffer中而不是连接),请使用Stream.collect(),它就是为此而设计的。

这里有一个代码示例,如果你尝试这样做,它会产生错误的答案。假设你想用一个假设的MutableInteger类做加法:

// Don't do this
MutableInteger result = stream.reduce(new MutableInteger(0), (a,b) -> a.add(b.get()));

这得到错误答案的原因之一是,如果我们并行拆分计算,现在两个计算共享相同的可变起始值。请注意:

a + b + c + d
= 0 + a + b + 0 + c + d  // 0 denotes identity
= (0 + a + b) + (0 + c + d) // associativity

因此,我们可以自由地拆分流,计算部分和0 + a + b0 + c + d,然后将结果相加。但如果它们共享相同的标识值,并且该值因其中一次计算而发生变化,则另一次计算可能以错误的值开始。

(请进一步注意,如果实现认为这是值得的,即使是顺序计算,也可以这样做。)

票数 13
EN

Stack Overflow用户

发布于 2014-05-26 21:01:26

这在语法上是允许的,但我认为这与设计模式背道而驰,是一个坏主意。

  static void accumulatorTest() {
     ArrayList<Point> points = new ArrayList<>();
     points.add(new Point(5, 6));
     points.add(new Point(0, 6));
     points.add(new Point(1, 9));
     points.add(new Point(4, 16));
     BinaryOperator<Point> sumPoints = new BinaryOperator<Point>() {
        public Point apply(Point p1, Point p2) {
           p2.x += p1.x;
           p2.y += p1.y;
           return new Point(p2); //return p2 and the list is transformed into running total
        }
     };
     Point sum = points.stream().reduce(new Point(0, 0), sumPoints); 
     System.out.println(sum);
     System.out.println(points);
  }

答案是正确的;我们得到了所有x和y坐标的和。修改原始列表,并通过输出确认:

java.awt.Pointx=10、y=37java.awt.Pointx=5、y=6、java.awt.Pointx=5、y=12、java.awt.Pointx=6、y=21、java.awt.Pointx=10、y=37]

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23869930

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档