美文网首页
stream 中的foreEach()调用分析

stream 中的foreEach()调用分析

作者: pengyuyancode | 来源:发表于2019-07-20 23:15 被阅读0次

    Stream.java对于forEach方法的解释:

    为该流的每个元素执行一个操作。该方法是一个终止操作;对于并行流来说,遍历顺序可能是不准确的。对于共享变量的操作,需要提供额外的同步机制。

     /**
         * Performs an action for each element of this stream.
         *
         * <p>This is a <a href="package-summary.html#StreamOps">terminal
         * operation</a>.
         *
         * <p>The behavior of this operation is explicitly nondeterministic.
         * For parallel stream pipelines, this operation does <em>not</em>
         * guarantee to respect the encounter order of the stream, as doing so
         * would sacrifice the benefit of parallelism.  For any given element, the
         * action may be performed at whatever time and in whatever thread the
         * library chooses.  If the action accesses shared state, it is
         * responsible for providing the required synchronization.
         *
         * @param action a <a href="package-summary.html#NonInterference">
         *               non-interfering</a> action to perform on the elements
         */
    void forEach(Consumer<? super T> action);
    

    该方法有俩个实现

    第一个位于 ReferencePipeline.java 中

    @Override
    public void forEach(Consumer<? super P_OUT> action) {
            evaluate(ForEachOps.makeRef(action, false));
    }
    

    第二个位于Head 中,它是ReferencePipeline.java 中的一个内部类

    static class Head<E_IN, E_OUT> extends ReferencePipeline<E_IN, E_OUT> {
    ........
    // Optimized sequential terminal operations for the head of the pipeline
            @Override
      public void forEach(Consumer<? super E_OUT> action) {
             if (!isParallel()) {
                    sourceStageSpliterator().forEachRemaining(action);
             }
             else {
                    super.forEach(action);
            }
     }
    .......
    }
    

    现在有俩端代码

    List<Integer> list= Arrays.asList(2,3,4,5,6);
    list.stream().forEach(System.out::println);
    
    List<Integer> list= Arrays.asList(2,3,4,5,6);
    list.stream().map(item->item).forEach(System.out::println);
    

    对于第一段代码stream.forEach(System.out::println),它会调用Head中的forEach()

    对于第二段代码stream().map(item->item).forEach(System.out::println)他会调用ReferencePipeline 中的forEach()

    原因:java8中对于Stream操作分为几个阶段:流源,中间操作,终止操作。

    list.stream().forEach(System.out::println);:流源+终止操作。而Head中的foreach()方法对于流源遍历做了优化。

    stream().map(item->item).forEach(System.out::println):map()操作是一个中间操作。对于有中间操作的流来说forEach()需要关注每个中间操作都做了什么,所以调用的是ReferencePipeline 中的forEach()

    相关文章

      网友评论

          本文标题:stream 中的foreEach()调用分析

          本文链接:https://www.haomeiwen.com/subject/hgsplctx.html