Reputation: 695
With the following code I always get 0 as the first output. Is that guaranteed?
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 );
}
According to 'peek' documents "... performing the provided action on each element as elements are consumed ...". However for non-parallel streams it has to be either before or after.
In other words, when the 'terminal operation' happens for an element is it removed from the pipeline before the terminal operation or after?
(I am pretty sure 'before' is the right answer, but trying to understand some complex stream code where the opposite seems to be assumed.)
Upvotes: 0
Views: 503
Reputation: 159135
Think about it. If you have a streaming pipeline like
...peek(xxx).map(...).peek(yyy).collect(...)
the xxx
code would see the element before the mapping function is applied, and the yyy
code would see the element after the mapping function is applied, and before the element is handed off to the final operation, as the element "flows" down the stream.
A particular element will be processed by the steps of the stream in the order of the stream pipeline, but there is generally no constraint on the order of different elements being processed, especially if stream is parallel.
E.g. the stream engine could decide to send all elements to the xxx
code, before mapping all the element, and then finally send all elements to the yyy
code. The stream pipeline would function correctly if it did. It won't, or course, because that defeats the purpose of streaming, but it would be valid to do so.
Upvotes: 1
Reputation: 15704
The function in peek
will always be called before the function in forEach
for each element.
Upvotes: 1