Java Stream 的中间操作(二)

上篇Stream Head的构建(一)我们用Collection.stream构建了源头,长相如下图

stream_source_head.png

此篇以集合为源,看一个简单的流的中间操作。

List names = Arrays.asList("one", "two", "three", "four");
 Stream stream = names.stream()
                //具体Lambda表达式或方法引用先不用管
                .filter(s -> s.length() > 2)
                .map(String::toUpperCase);

在上图中把源头设为stream0,接下来filter(...)在stream0上操作,返回一个中间流StatelessOp,和Head一样也是ReferencePipeline子类

ReferencePipeline.java
public final Stream filter(Predicate predicate) {
        Objects.requireNonNull(predicate);
        //这里this就是stream0
        return new StatelessOp(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SIZED) {
            @Override
            public Sink opWrapSink(int flags, Sink sink) {
            //这里实现了重要的抽象方法opWrapSink,以一个Sink作为参数,又返回一个Sink,先忽略
               ...
            }
        };
    }

我们只看StatelessOp的构造方法

public StatelessOp(AbstractPipeline upstream,inputShape,opFlags) {
            super(upstream, opFlags); 
        }

和Head一样也是调用的AbstractPipeline构造方法,只不过Head调用的是专门构造源头的,StatelessOp或StatefulOp调用的是专门构造中间管道的。

AbstractPipeline.java
//previousStage就是stream0
AbstractPipeline(AbstractPipeline previousStage, int opFlags) {
        if (previousStage.linkedOrConsumed)
            throw new IllegalStateException(MSG_STREAM_LINKED);
        previousStage.linkedOrConsumed = true;
        //上个stream的next指向自己
        previousStage.nextStage = this;
        //自己的previous指向上个 stream
        this.previousStage = previousStage;
        this.sourceOrOpFlags = opFlags & StreamOpFlag.OP_MASK;
        this.combinedFlags = StreamOpFlag.combineOpFlags(opFlags, previousStage.combinedFlags);
        this.sourceStage = previousStage.sourceStage;
        if (opIsStateful())
            sourceStage.sourceAnyStateful = true;
        this.depth = previousStage.depth + 1;
    }

filter方法调用完后,如下图


stream_filter.png

再看map,在stream1上操作,和filter雷同

ReferencePipeline.java
public final  Stream map(Function mapper) {
        Objects.requireNonNull(mapper);
        return new StatelessOp(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
            @Override
            public Sink opWrapSink(int flags, Sink sink) {
                ...同上
            }
        };
    }

stream_map.png

这个过程其实就是一个双向链表的构建,但每个中间流都含有源头的引用,为啥呢?图片来自
https://cloud.tencent.com/developer/article/1333533

stream_structure.png

还有些中间操作,如sorted,flatMap都类似,暂且不表。到此并没有实际的计算,接下来再看Java Strem 的终止操作(三)。

你可能感兴趣的:(Java Stream 的中间操作(二))