使用以下代码,我总是得到0作为第一个输出。这有保证吗?
import java.util.Random;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.rope();
}
class Wrapper {
public int x = 0;
}
void rope() {
Stream.generate( Wrapper::new ).limit(100000)
.peek( w -> asum += w.x )
.forEach( w -> mutate( w ) );
System.out.println( asum );
System.out.println( bsum );
}
void mutate( Wrapper w ) {
w.x = r.nextInt(2);
bsum += w.x;
}
protected long asum = 0;
protected long bsum = 0;
Random r = new Random( 0 );
}
根据' peek'文档" ...对每个元素执行提供的操作作为元素被使用..."。但是对于非并行流,它必须在之前或之后。
换句话说,当'终端操作'对于一个元素,是在终端操作之前还是之后从管道中删除?
(我非常确定'之前是正确的答案,但试图了解一些复杂的流代码,其中似乎假设相反。)
答案 0 :(得分:1)
peek
中的函数将始终在forEach
中的函数之前为每个元素调用。
答案 1 :(得分:1)
想一想。如果您有像
这样的流媒体管道 ...peek(xxx).map(...).peek(yyy).collect(...)
xxx
代码会在应用映射函数之前看到元素,而yyy
代码会在映射后看到元素函数被应用,在元素被移交给最终操作之前, as 元素"流动"沿着溪流。
特定元素将按流管道顺序由流的步骤处理,但通常对正在处理的不同元素的顺序没有约束,特别是如果流是并行的。
E.g。在映射所有元素之前,流引擎可以决定将所有元素发送到xxx
代码,然后最终将所有元素发送到yyy
代码。如果确实如此,流管道将正常运行。它不会或当然,因为这会破坏流媒体的目的,但这样做有效。