stream 中的foreEach()调用分析

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

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

 /**
     * Performs an action for each element of this stream.
     *
     * 

This is a terminal * operation. * *

The behavior of this operation is explicitly nondeterministic. * For parallel stream pipelines, this operation does not * 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 * non-interfering action to perform on the elements */ void forEach(Consumer action);

该方法有俩个实现

第一个位于 ReferencePipeline.java 中

@Override
public void forEach(Consumer action) {
        evaluate(ForEachOps.makeRef(action, false));
}

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

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

现在有俩端代码

List list= Arrays.asList(2,3,4,5,6);
list.stream().forEach(System.out::println);
List 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()调用分析)