Java8 Stream API 之 IntPipeline(一) 源码解析

本文详细介绍了Java8 Stream API中的IntPipeline,包括PipelineHelper、Sink、IntPipeline的实现原理,特别是filter、peek、forEach、forEachOrdered等操作的源码解析,并探讨了并行执行的ForEachTask和ForEachOrderedTask。
摘要由CSDN通过智能技术生成

目录

一、PipelineHelper / AbstractPipeline

二、Sink

三、IntPipeline

1、filter / peek

2、forEach / forEachOrdered

3、ForEachOps

4、测试用例

5、IntStream range/rangeClosed

6、ForEachTask

7、ForEachOrderedTask


本篇博客继续上一篇《Java8 Stream API 之 IntStream 用法全解》探讨IntPipeline 各接口的实现细节。

一、PipelineHelper / AbstractPipeline

       PipelineHelper 是一个抽象类,用于帮助流处理动作的执行,但是该类的所有方法都是抽象方法,即相当于一个接口类,AbstractPipeline继承自PipelineHelper,提供了所有抽象方法的默认实现,除了makeNodeBuilder以外,该接口包含的方法如下:

      AbstractPipeline定义了不少属性和方法,相关方法的说明在后面子类的实现中再做探讨,这里重点关注其属性定义和构造方法实现,如下:

    /**
     * 初始的包含待处理元素的流
     */
    @SuppressWarnings("rawtypes")
    private final AbstractPipeline sourceStage;

    /**
     * 上一个流处理动作,如果当前实例是第一个流处理动作,则该属性为null
     */
    @SuppressWarnings("rawtypes")
    private final AbstractPipeline previousStage;

    /**
     * 当前流处理动作的操作标识
     */
    protected final int sourceOrOpFlags;

    /**
     * 当前流处理动作的下一个流处理动作
     */
    @SuppressWarnings("rawtypes")
    private AbstractPipeline nextStage;

    /**
     * 非终止类型的流处理动作的个数
     */
    private int depth;

    /**
     * 在此之前的流处理动作包括当前流处理的所有操作标识
     */
    private int combinedFlags;

    /**
     * 当前流处理对应的Spliterator
     */
    private Spliterator<?> sourceSpliterator;

    /**
     * The source supplier. Only valid for the head pipeline. Before the
     * pipeline is consumed if non-null then {@code sourceSpliterator} must be
     * null. After the pipeline is consumed if non-null then is set to null.
     */
    private Supplier<? extends Spliterator<?>> sourceSupplier;

    /**
     * 表示流处理是否已经开始
     */
    private boolean linkedOrConsumed;

    /**
     * True if there are any stateful ops in the pipeline; only valid for the
     * source stage.
     */
    private boolean sourceAnyStateful;

    private Runnable sourceCloseAction;

    /**
     * 是否并行流处理
     */
    private boolean parallel;
  AbstractPipeline(Supplier<? extends Spliterator<?>> source,
                     int sourceFlags, boolean parallel) {
        this.previousStage = null;
        this.sourceSupplier = source;
        this.sourceStage = this;
        this.sourceOrOpFlags = sourceFlags & StreamOpFlag.STREAM_MASK;
        // The following is an optimization of:
        // StreamOpFlag.combineOpFlags(sourceOrOpFlags, StreamOpFlag.INITIAL_OPS_VALUE);
        this.combinedFlags = (~(sourceOrOpFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE;
        this.depth = 0;
        this.parallel = parallel;
    }

   
    AbstractPipeline(Spliterator<?> source,
                     int sourceFlags, boolean parallel) {
        this.previousStage = null;
        this.sourceSpliterator = source;
        this.sourceStage = this;
        this.sourceOrOpFlags = sourceFlags & StreamOpFlag.STREAM_MASK;
        // The following is an optimization of:
        // StreamOpFlag.combineOpFlags(sourceOrOpFlags, StreamOpFlag.INITIAL_OPS_VALUE);
        this.combinedFlags = (~(sourceOrOpFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE;
        this.depth = 0;
        this.parallel = parallel;
    }

    //previousStage表示上一个流处理动作
    AbstractPipeline(AbstractPipeline<?, E_IN, ?> previousStage, int opFlags) {
        if (previousStage.linkedOrConsumed)
            throw new IllegalStateException(MSG_STREAM_LINKED);
        //设置previousStage同当前Stage的关系
        previousStage.linkedOrConsumed = true;
        previousStage.nextStage = this;
        
        //设置当前Stage的属性
        this.previousStage = previousStage;
        this.sourceOrOpFlags = opFlags & StreamOpFlag.OP_MASK;
        this.combinedFlags = StreamOpFlag.combineOpFlags(opFlags, previousStage.combinedFlags);
        this.sourceStage = previousStage.sourceStage;
        if (opIsStateful()) //opIsStateful由子类实现
            sourceStage.sourceAnyStateful = true;
        //depth属性加1
        this.depth = previousStage.depth + 1;
    }

 AbstractPipeline是抽象类,定义了多个必须由子类实现的抽象方法,如下:

其中StreamShape是一个枚举值,表示Stream API支持的流元素类型,其定义如下:

各方法的用途在后面的子类实现中会逐一讲解。 

二、Sink

      Sink表示多个流处理动作中的一个,比如fiter方法对应的流处理动作,该类是一个继承自Consumer的接口类,其定义如下:

待D标记的6个方法都是空实现的default方法,要求在开始第一次调用accept方法前必须调用begin方法通知Sink 即将处理流中的元素,begin方法的参数表示即将处理的流元素的个数,如果个数未知则传-1;在流中所有的元素都处理完成后必须调用end方法通过Sink流处理已经结束了。在调用end方法后,不能再次调用accept方法,除非再次调用begin方法。如果不希望Sink继续处理,可以调用cancellationRequested方法终止流元素的处理。

Of开头的三个接口类继承自Sink,改写了对应类型的accept方法,以OfInt为例说明,如下:

其中Tripwire是java.util.stream相关类使用的打印debug日志的工具类,如果org.openjdk.java.util.stream.tripwire属性为true,则Tripwire.ENABLED为true,默认为false。

Chained开头的四个类都是Sink接口的抽象实现类,以ChainedInt为例说明,其实现如下:

这里的downstream表示下一个流处理动作对应的Sink,子类只需实现其accept方法即可。 

三、IntPipeline

      IntPipeline没有新增属性,我们直接看起方法的实现细节。IntPipeline实现了AbstractPipeline的大部分抽象方法,除了opIsStateful和opWrapSink外,这两个方法由子类去实现。

1、filter / peek

      filter方法用于过滤流中的元素,peek通常用于打印流处理中的元素,其实现如下:

 @Override
public final IntStream filter(IntPredicate predicate) {
        Objects.requireNonNull(predicate); //非空校验
        //返回一个新的IntStream实例
        return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                        StreamOpFlag.NOT_SIZED) {
            //传入的sink表示下一个流处理动作,被赋值给downstream
            @Override
            Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                return new Sink.ChainedInt<Integer>(sink) {
                    @Override
                    public void begin(long size) {
                        //通知下一个Sink流处理开始,个数未知
                        //此处downstream实际就是上面的入参sink
                        downstream.begin(-1);
                    }

                    @Override
                    public void accept(int t) {
                        if (predicate.test(t))
                            //返回true以后才将t传递给下一个Sink
                            downstream.accept(t);
                    }
                };
            }
        };
    }

@Override
    public final IntStream peek(IntConsumer action) {
        Objects.requireNonNull(action);
        return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                        0) {
            @Override
            Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                return new Sink.ChainedInt<Integer>(sink) {
                    @Override
                    public void accept(int t) {
                        action.accept(t);
                        //不做任何处理,将t直接传递给下一个流处理动作
                        downstream.accept(t);
                    }
                };
            }
        };
    }

abstract static class StatelessOp<E_IN> extends IntPipeline<E_IN> {
        
        StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
                    StreamShape inputShape, //描述流元素的类型
                    int opFlags) {
            super(upstream, opFlags);
            //校验两者流元素类型一致
            assert upstream.getOutputShape() == inputShape;
        }

        @Override
        final boolean opIsStateful() {
            return false; //返回false,表示无状态操作
        }
    }

//upstream 表示上一个流处理动作
IntPipeline(A
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值