简体   繁体   中英

Does Java Stream 'peek' happen just before or just after the terminal operation?

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.)

对于每个元素,始终会在forEach的函数之前调用peek的函数。

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.

Eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM