AbstractPipeline<?, E_IN, ?> upstream //upstram代表Stream对象
Sink<? super E_OUT> downstream //downstream代表Sink对象
- 源建立:
Stage0 Head节点 stage0.depth=0;
- 中间操作:
创建 | 操作 | 主要核心 |
Stage1 | filter() | stage0.nextStage = stage1; stage1.upstream = stage0; stage1.depth=1; |
Stage2 | sorted() | stage1.nextStage = stage2; stage2.upstream = stage1; stage2.depth=2; |
Stage3 | limit() | stage2.nextStage = stage3; stage3.upstream = stage2; stage3.depth=3; |
若干个中间操作的链接是双向链表,中间操作仅仅是完成双向链表,实际不运行业务逻辑,中间操作可以理解成建立Stage阶段的过程。
- 终端操作:
collect终端操作:不在是创建Stage阶段,返回值也不在是Stream对象
collect()方法内部的逻辑会调用helper.wrapAndCopyInto(reducingSink,spliterator)方法;该方法又可分为调用wrapSink()方法和copyInto()方法来讲解。
- helper.wrapAndCopyInto(reducingSink,spliterator);
wrapSink()方法,是由终端Sink倒退至第一阶段Stage1,循环处理,依次生成Sink3,Sink2,Sink1,最终的Sink1就是wrappedSink对象,wrappedSink对象是单向链表结构,前一个Sink内部有数据成员downstream指向下一个Sink。
copyInto()方法,就是启动流水线开始真正执行,数据源中的数据倒入管道,按照wrappedSink封装好的行为来执行。
源码:跟踪Stream串行流工作原理
由代码跟踪,观察Stream工作原理(以下讲解的是非并行执行时的Stream工作原理)
List<String> list = Arrays.asList("are", "where", "anvato", "java", "abc");
List<String> result =
list.stream() //定义输入源, 得到Stage0 Head节点(流)
.filter(s -> s.startsWith("a")) //定义中间操作, 得到Stage1 StatelessOp节点(流)
.sorted() //定义中间操作, 得到Stage2 StatefulOp节点(流),SortedOps.OfRef实例
.limit(3) //定义中间操作, 得到Stage3 StatefulOp节点(流),SliceOps的StatefulOp实例
.collect(Collectors.toList()); //定义终端操作, TerminalOp节点(流),ReduceOp实例
list.stream()语句:分析
list.stream(){
StreamSupport.stream(spliterator(), false);
}
//spliterator() //获得拆分器 Collection接口的默认方法
return Spliterators.spliterator(this, 0){ //这里的this指的是当前list,特性值0
return new IteratorSpliterator<>(collection, characteristics){}
}
//stream(spliterator, false); //StreamSupport类的静态方法
return new ReferencePipeline.Head<>(
spliterator, //可拆分的迭代器,上面已经拿到
StreamOpFlag.fromCharacteristics(spliterator), //特性值为0
parallel); //传进来的false 说明不并行处理
/**
* 自此:我们拿到了Head节点,也即Stage0阶段已经建立完毕
*/
list.stream()语句:结果:我们拿到了Head节点,也即Stage0阶段已经建立完毕
Stage0.filter(s -> s.startsWith("a")) 语句:分析
//调用filter方法时,是Head节点也即Stage0阶段 调用的,所以filter的入参this是Head节点对象
public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_SIZED) {
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
//创建Stage阶段,用不到opWrapSink方法,
//终端操作时,才会驱动,调用该方法来建立一个单链的wrappedSink
}
};
}
//StatelessOp类的构造函数
StatelessOp(AbstractPipeline<?, E_IN, ?> upstream, StreamShape inputShape, int opFlags) {
super(upstream, opFlags){
upstream.nextStage = this; //Stage0的下一阶段是Stage1 双向链表的建立
this.upstream = upstream; //Stage1的前一阶段是Stage0 双向链表的建立
this.depth = upstream.depth + 1; //Stage1的深度是1
//...
}
}
/**
* filter方法调用后,我们得到了Stage1阶段,并且建立好了双向链表
*/
Stage0.filter()语句:结果:我们拿到了中间操作filter的节点,也即Stage1阶段已经建立完毕,并建立好双向链表
Stage1.sorted()语句:分析
public final Stream<P_OUT> sorted() {
return SortedOps.makeRef(this); //这个this是当前的Stage1
}
static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream) {
return new OfRef<>(upstream);
}
//SortedOps的内部类OfRef 继承StatefulOp
private static final class OfRef<T> extends ReferencePipeline.StatefulOp<T, T> {
OfRef(AbstractPipeline<?, T, ?> upstream) {
super(upstream, StreamShape.REFERENCE, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
//...
}
public Sink<T> opWrapSink(int flags, Sink<T> sink){
//这里先注释掉,创建Stage2阶段用不到opWrapSink方法
//return new RefSortingSink<>(sink, comparator);
}
}
//父类StatefulOp的构造函数
StatefulOp(AbstractPipeline<?, E_IN, ?> upstream, StreamShape inputShape, int opFlags) {
super(upstream, opFlags){
upstream.nextStage = this; //Stage1的下一阶段是Stage2
this.upstream = upstream; //Stage2的前一阶段是Stage1
this.depth = upstream.depth + 1; //Stage2的深度为2
sourceStage.sourceAnyStateful = true; //说明本流管道中有的中间操作是有状态的
//...
}
}
/**
* sorted方法调用后,我们得到了Stage2阶段,并且建立好了双向链表
*/
Stage1.sorted()语句:结果:我们拿到了中间操作sorted的节点,也即Stage2阶段已经建立完毕,并建立好双向链表
Stage2.limit(3)语句:分析
public final Stream<P_OUT> limit(long maxSize) {
return SliceOps.makeRef(this, 0, maxSize); //这里的this指的是Stage2
}
public static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream, long skip, long limit) {
return new ReferencePipeline.StatefulOp<T, T>(upstream, StreamShape.REFERENCE, flags(limit)) {
Sink<T> opWrapSink(int flags, Sink<T> sink) {
//创建Stage3时用不到opWrapSink方法,先注释掉
}
};
}
//StatefulOp类的构造函数
StatefulOp(AbstractPipeline<?, E_IN, ?> upstream, StreamShape inputShape, int opFlags) {
super(upstream, opFlags){
upstream.nextStage = this; //Stage2的下一阶段是Stage3
this.upstream = upstream; //Stage3的前一阶段是Stage2
this.depth = upstream.depth + 1; //Stage3的深度为3
sourceStage.sourceAnyStateful = true; //本流管道中有的中间操作是有状态的
//...
}
}
/**
* limit()方法调用后,我们得到了Stage3阶段,并且建立好了双向链表
*/
Stage2.limit()语句:结果:我们拿到了中间操作limit的节点,也即Stage3阶段已经建立完毕,并建立好双向链表
插图:::::::::::::::::::::::::::::::::::
Stage3.collect()语句:分析:步骤1,拿到TerminalOp终端操作对象(包装了终端ReducingSink和evaluateSequential方法)
public final <R, A> R collect(Collector<? super P_OUT, A, R> collector) {
A container = evaluate(ReduceOps.makeRef(collector));
return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)
? (R) container
: collector.finisher().apply(container);
}
//ReduceOps类的makeRef方法
public static <T, I> TerminalOp<T, I> makeRef(Collector<? super T, I, ?> collector) {
Supplier<I> supplier = collector.supplier(); //工厂
BiConsumer<I, ? super T> accumulator = collector.accumulator(); //累积器
BinaryOperator<I> combiner = collector.combiner(); //累积的组合操作
class ReducingSink extends Box<I> implements AccumulatingSink<T, I, ReducingSink> {
public void begin(long size) {
state = supplier.get();
}
public void accept(T t) {
accumulator.accept(state, t);
}
public void combine(ReducingSink other) {
state = combiner.apply(state, other.state);
}
}
return new ReduceOp<T, I, ReducingSink>(StreamShape.REFERENCE) {
public ReducingSink makeSink() {
return new ReducingSink();
}
};
}
//请注意:终端ReduceOp不再是流Stream,其内部封装了终端sink对象以及evaluateSequential方法
private static abstract class ReduceOp<T, R, S extends AccumulatingSink<T, R, S>> implements TerminalOp<T, R> {
public <P_IN> R evaluateSequential(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
return helper.wrapAndCopyInto(makeSink(), spliterator).get();
}
}
Stage3.collect()语句:分析:步骤2,拿到TerminalOp终端操作对象之后,调用evaluate()方法,evaluate()方法内部跟踪到调用了helper.wrapAndCopyInto()方法
/**
* 以上我们得到了一个TerminalOp实例(封装了终端Sink以及evaluateSequential方法),然后传递给evaluate()方法,我们继续看evaluate()方法
*/
final <R> R evaluate(TerminalOp<E_OUT, R> terminalOp) {
return terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags())); //调用了TerminalOp的evaluateSequential方法
}
public <P_IN> R evaluateSequential(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
return helper.wrapAndCopyInto(makeSink(), spliterator).get();
}
Stage3.collect()语句:分析:步骤3,helper.wrapAndCopyInto()方法
/**
* helper.wrapAndCopyInto()方法调用,makeSink()得到的是终端ReducingSink对象
*/
final <P_IN, S extends Sink<E_OUT>> S wrapAndCopyInto(S sink, Spliterator<P_IN> spliterator) {
copyInto(wrapSink(sink), spliterator);
return sink; //这里的sink是ReducingSink对象,所以可以调用sink.get()拿到最终的结果
}
Stage3.collect()语句:分析:步骤4,wrapSink()方法,得到了最终的Sink单向链表对象,主要表达了Sink接口的四个抽象方法的调用,begin()、end()、accept()、cancellationRequested()方法。每一个阶段Stage的这几个方法都被单向链了起来。
/**
* wrapSink方法:组织Sink单向链表,sink是从前向后的
*/
final <P_IN> Sink<P_IN> wrapSink(Sink<E_OUT> sink) {
//这里的this是最后一个中间操作:Stage3
//逐步的倒退调用来组织Sink链,阶段Stage1~3的Sink的生成策略是:当前阶段的opWrapSink方法
for ( @SuppressWarnings("rawtypes") AbstractPipeline p=AbstractPipeline.this; p.depth > 0; p=p.previousStage) {
sink = p.opWrapSink(p.previousStage.combinedFlags, sink);
}
return (Sink<P_IN>) sink;
}
//我们一步步的分析各个阶段的Sink对象是怎么形成的,先从Stage3开始
//Stage3的opWrapSink()方法
Stage3.opWrapSink(Stage2.conbinedFlags,ReducingSink){
return new Sink.ChainedReference<T, T>(sink) { //入参sink为ReducingSink
long n = skip; //n=0
long m = limit >= 0 ? limit : Long.MAX_VALUE; //m=3
public void begin(long size) {
downstream.begin(calcSize(size, skip, m)); //downstream为ReducingSink,calcSize()为3
}
public void accept(T t) {
if (n == 0) {
if (m > 0) {
m--;
downstream.accept(t);
}
}
else {
n--;
}
}
public boolean cancellationRequested() {
return m == 0 || downstream.cancellationRequested();
}
};
}
//得到Stage3的Sink3后,继续for循环,去创建Sink2(sorted操作的opWrapSink方法是返回一个RefSortingSink对象)
private static final class RefSortingSink<T> extends AbstractRefSortingSink<T> {
private ArrayList<T> list;
RefSortingSink(Sink<? super T> sink, Comparator<? super T> comparator) {
super(sink, comparator);
}
@Override
public void begin(long size) {
list = (size >= 0) ? new ArrayList<T>((int) size) : new ArrayList<T>();
}
@Override
public void end() {
list.sort(comparator);
downstream.begin(list.size());
if (!cancellationWasRequested) {
list.forEach(downstream::accept);
}
else {
for (T t : list) {
if (downstream.cancellationRequested()) break;
downstream.accept(t);
}
}
downstream.end();
list = null;
}
@Override
public void accept(T t) {
list.add(t);
}
}
//得到Stage2的Sink2后,继续for循环,去创建Sink1
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
public void begin(long size) {
downstream.begin(-1);
}
public void accept(P_OUT u) {
if (predicate.test(u))
downstream.accept(u);
}
};
}
//得到Sink1后,再往前的Head节点,其深度为0,所以此时的Sink1就是我们最终循环处理完后的wrappedSink对象
Stage3.collect()语句:分析:步骤4,wrapSink()方法的结果:最终得到的wrappedSink对象大概如下:
/**
* Sink主要结构可以总结为:
*
* 拥有一个数据成员downstream,也即下游Sink
*
* 拥有四个方法:begin() accept() end() cancellationRequested()
*/
wrappedSink
{
public void begin(long size) {//Stage1.begin
Stage2.begin(size){//Stage2.begin
list = (size >= 0) ? new ArrayList<T>((int) size) : new ArrayList<T>();
}
}
public void accept(P_OUT u) {//Stage1.accept
if (predicate.test(u))
Stage2.accept(u){//Stage2.accept
list.add(t); //这也是sorted方法为什么就堵在这里,直至所有元素都到达的原因所在,因为这里没接着调用Stage3.accept()方法
//那么Stage3在哪里得到执行的呢? 答:在end()方法这里
}
}
public void end() {//Stage1.end
Stage2.end(){//Stage2.end
list.sort(comparator);
Stage3.begin(list.size()){ //Stage3.begin
ReducingSink.begin(calcSize(size, skip, m)){ //ReducingSink.begin
state = supplier.get(); //得到初始值
}
}
if (!cancellationWasRequested) {
list.forEach(Stage3::accept{ //Stage3.accept
if (m > 0) {
m--;
ReducingSink.accept(t){ //ReducingSink.accept
accumulator.accept(state, t)//累积器进行累积元素t
}
}
});
}
Stage3.end();//Stage3.end
list = null;
}
}
public boolean cancellationRequested() {
return Stage2.cancellationRequested(){
return Stage3.cancellationRequested(){
return m == 0 || ReducingSink.cancellationRequested();
}
}
}
}
Stage3.collect()语句:分析:步骤5,copyInto()方法
final <P_IN> void copyInto(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator) {
if (!StreamOpFlag.SHORT_CIRCUIT.isKnown(getStreamAndOpFlags())) {
wrappedSink.begin(spliterator.getExactSizeIfKnown());
spliterator.forEachRemaining(wrappedSink);
wrappedSink.end();
}
else {
copyIntoWithCancel(wrappedSink, spliterator);
}
}
spliterator.forEachRemaining(wrappedSink){
//流中的每个元素进行消费 accept(T t)方法的调用
}
附录:附上Sink函数接口的简易代码:
/**
* Sink主要结构可以总结为:
*
* 拥有一个数据成员downstream,也即下游Sink
*
* 拥有四个方法:begin() accept() end() cancellationRequested()
*/
interface Sink<T> extends Consumer<T> {
default void begin(long size) {}
default void end() {}
default boolean cancellationRequested() { return false; }
static abstract class ChainedReference<T, E_OUT> implements Sink<T> {
protected final Sink<? super E_OUT> downstream; //代表下一个Sink对象
public ChainedReference(Sink<? super E_OUT> downstream) {
this.downstream = Objects.requireNonNull(downstream); //当前Sink的downstream字段指向下一个Sink 所以Sink链是个单向链表
}
@Override
public void begin(long size) {
downstream.begin(size);
}
@Override
public void end() {
downstream.end();
}
@Override
public boolean cancellationRequested() {
return downstream.cancellationRequested();
}
}
}
Sink链是单向的,从前指向后...