目录
一、PipelineHelper / AbstractPipeline
本篇博客继续上一篇《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