如果只对BinaryOperator参数中的一个进行了总结,Java流实际上减少了什么?

如果只对BinaryOperator参数中的一个进行了总结,Java流实际上减少了什么?,java,java-stream,Java,Java Stream,看看下面的代码:在二进制运算符中,我们有reduce((x,y)->x+x)。为什么实际计算为可选[512]?我没有解释 System.out.println((Stream.generate(()->1d).limit(10). peek((doubleValue)->{ System.out.println("Call the first peek: "+doubleValue); }).

看看下面的代码:在二进制运算符中,我们有reduce((x,y)->x+x)。为什么实际计算为可选[512]?我没有解释

System.out.println((Stream.generate(()->1d).limit(10).
            peek((doubleValue)->{
                System.out.println("Call the first peek: "+doubleValue);
            }).
            reduce((x,y)->x+x)));
这里是输出:为了向你们澄清,我在peek部分展示了单个的x是1.0

Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Optional[512.0]

所以问题是,在获得可选[512]之前,什么控制reduce工作?

因为您有10个参数,但操作是9。2^9=512

从技术上讲,Stream reduce在您这样做时不提供任何一致性

仅在关联约化运算中提供保证,而您的保证则不是(它考虑第一个操作数而忽略第二个操作数)

测试代码时,您正在观察结果

这些结果在试图对非平行流中如何实现还原进行有根据的猜测时并不令人惊讶。然而,这些结果并没有得到Stream文档的保证,因为您不尊重这些需求


例如,结果可能是1或2。尽管有点令人费解,但它仍然有意义,而且您不符合要求。

让我们看看这里发生了什么:

    System.out.println((Stream.generate(()->1d).limit(10).
            reduce((x,y)-> {
                double ret = x+x;
                System.out.println(ret);
                return ret;
            })));
输出是

2.0
4.0
8.0
16.0
32.0
64.0
128.0
256.0
512.0
Optional[512.0]

因为您的流中有10个参数提供给,具有默认的起始值
0


由于您使用的是
(x,y)->x+x
,并且您实际上将结果加倍为
结果的9倍以上,我只是检查了x+x应该如何在BinaryOperatorBeek输出中表现出来,这对我来说没问题,可选值存在问题,您可以通过打印其参数来查看reduce函数是如何调用的:
.reduce((x,y)-{{St.Out.PrtLnn(“x=”+x+),y=“+y”;返回x+x;})) @ ErnestStk感谢与Maynks@ ZhenyaM共享的打印思想,因此它甚至在没有Y使用的情况下聚合它。@ IyayayvLAMPIV认为你的减数为这个代码>(1,1)-> 1 + 1…(2,1) -> 2+2 .... (256,1)->256+256
@IlyaYevlampiev
y
表示流的下一个元素,其中
x
表示旧的reduce结果。因此,在你的情况下——是的,忽略