在java 8中,stream有一个reduce方法:
T reduce(T identity, BinaryOperator<T> accumulator);
是否允许累加器运算符修改其参数之一?我认为不是因为javadoc说累加器应该是非干涉的,尽管所有的例子都谈到修改集合,而不是修改集合的元素。
举个具体的例子,如果我们
integers.reduce(0, Integer::sum);
假设一下 Integer
是可变的,是吗 sum
是否允许通过在第一个参数中添加第二个参数的值来修改第一个参数?
我想不会,但我也想举一个例子,说明这种干涉会导致什么问题。
2条答案
按热度按时间q5lcpyga1#
不可以。累加器不应该修改它的参数;它接受两个值并生成一个新值。如果要在累积过程中使用变异(例如,将字符串累积到stringbuffer中而不是串联),请使用
Stream.collect()
,它是为此而设计的。下面是一个代码示例,如果您尝试此操作,它会生成错误的答案。假设要对假设的mutableinteger类进行加法:
得到错误答案的一个原因是,如果我们并行分解计算,现在两个计算共享相同的可变起始值。请注意:
所以我们可以自由地分割数据流,计算部分和
0 + a + b
以及0 + c + d
,然后添加结果。但是,如果它们共享相同的标识值,并且该值由于其中一个计算而发生变化,则另一个可能以错误的值开始。(请进一步注意,即使对于顺序计算,如果它认为这是值得的,也允许实现这样做。)
zazmityj2#
这在语法上是允许的,但我认为这违背了设计模式,是个坏主意。
答案是正确的;我们得到所有x和y坐标的和。修改原始列表,由输出确认:
java.awt.point[x=10,y=37][java.awt.point[x=5,y=6],java.awt.point[x=5,y=12],java.awt.point[x=6,y=21],java.awt.point[x=10,y=37]]