Java-stream(2) Stream流水线解决方案

一、概述

Stream采用了流水线的形式来处理这些流数据。首先记录用户每一步的操作(这时候不会执行),当用户调用结束操作时将之前记录的操作叠加到一起在一次迭代中全部执行

更形象地说,用户在代码里写下一系列流操作后,就表示一条Stream流水线生成了,这个流水线就称为流管道(stream pipeline)。首先,是记录这条流水线上都有哪些阶段(stage),一个stage表示一个完整的操作,及这个流水线上处理数据的一个节点。当记录完成后,将数据从流水线的头(数据源)开始流入,在每一个节点(stage)对数据进行相应的操作,再流向下一个节点,直到遇到终结操作,完成流水线作业。
Java-stream(2) Stream流水线解决方案_第1张图片
看完Stream流水线的基本结构,继续解决下面几个问题:

  • 用户的操作如何记录?
  • 操作如何叠加?
  • 叠加之后的操作如何执行?
  • 执行后的结果(如果有)在哪里?

二、用户的操作如何记录?

stream中使用stage的概念来描述一个完整的操作,并用PipelineHelper实例来代表stage,将具有先后顺序的各stage连到一起,就构成了整个流水线。一个流管道包含了一个数据源,零个或者多个中间stage和一个终结stage。

PipelineHelper

PipelineHelper是一个帮助器类,用于执行流管道,在一个位置捕获流管道的所有信息(输出形状、中间操作、流标志、并行度等)。
一个PipelineHelper描述了流管道的初始状态,包括了它的数据源、中间操作和额外的并行信息,和在这个PipelineHelper的最后一个中间操作之后的终端(或有状态)操作的信息。PipelineHelper被传递到子类方法,它可以使用PipelineHelper来访问有关管道的信息,如头部形状、流标志和大小,并使用帮助器方法来执行管道操作。

主要方法(都是Abstract方法):

序号 方法名 入参 出参 功能说明
1 getSourceShape int 获取流管道的数据源形状,StreamShape具体参见:
2 getStreamAndOpFlags Spliterator spliterator long 合并来自流源、所有中间操作和终端操作的输出流和标志
3 exactOutputSizeIfKnown S sink, Spliterator spliterator > S 返回当前stage输出流数据的大小,如果未知或已知无穷大,则返回-1
4 wrapAndCopyInto Sink wrappedSink, Spliterator spliterator void 将当前stage应用于提供的spliterator,并将结果发送给提供的sink
5 copyInto Sink sink 将获取的元素发送给提供的sink,如果流管道已知是短路stage,那么在每次发送元素后都会判断一下是否可以停止发送元素的操作了
6 wrapSink Sink sink Sink 获取一个接收PipelineHelper输出类型元素的sink,并将其包装为接受输入类型元素并实现此PipelineHelper描述的所有中间操作的sink,将结果传递到提供的sink中
7 makeNodeBuilder long exactSizeIfKnown,IntFunction generator Node.Builder 构造一个节点生成器
8 evaluate Spliterator spliterator, boolean flatten,IntFunction generator Node 收集将管道stage应用于源Spliterator并将其应用到节点中所产生的所有输出元素
PipelineHelper的继承关系

PipelineHelper的继承关系如下:
Java-stream(2) Stream流水线解决方案_第2张图片
其中Head表示的是流水线里的第一个stage,即调用调用诸如Collection.stream()方法产生的Stage,很显然这个Stage里不包含任何操作;StatelessOp和StatefulOp分别表示无状态和有状态的Stage,对应于无状态和有状态的中间操作

IntPipeline, LongPipeline, DoublePipeline这三个类专门为三种基本类型(不是包装类型)而定制的,跟Re

你可能感兴趣的:(Java,java)