浅析java stream 源码
介绍
stream的结构有点像双向链表,节点之间通过引用连接。节点可以分为三类,控制数据输入的节点、操作数据的中间节点和控制数据输出的节点。
ReferencePipeline 包含了控制数据流入的 Head ,中间操作 StatelessOp, StatefulOp,终止操作 TerminalOp。
Lazy evaluation懒加载
stream表达式在被终极操作方法调用之前不会被赋值计算。Stream API中的大多数操作会返回一个Stream。这些操作不会做任何的执行操作,它们只会构建这个管道。
特征
特征:
Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
类图各个部分的主要功能是:
1、主要是各种操作的工厂类、数据的存储结构以及收集器的工厂类等;
2、主要用于Stream的惰性求值实现;
3、Stream的并行计算框架;
4、存储并行流的中间结果;
5、终结操作的定义;
BaseStream规定了流的基本接口,比如iterator、spliterator、isParallel等;
Stream中定义了map、filter、flatmap等用户关注的常用操作;
PipelineHelper主要用于Stream执行过程中相关结构的构建;
Head、StatelessOp、StatefulOp为ReferencePipeline中的内部类。
stream常用的流操作包括:
中间操作(intermediate Operations)
无状态(Stateless)操作:每个数据的处理都是独立的,不会影响或依赖之前的数据,如filter()、flatMap()、flatMapToDouble()、flatMapToInt()、flatMapToLong()、map()、mapToDouble()、mapToInt()、mapToLong()、peek()、unordered() 等。
有状态(Stateful)操作:处理时会记录状态。后面元素的处理会依赖前面的记录状态或者拿到所有元素才能继续下去。如
distinct()、sorted()、sorted(comparator)、limit()、skip() 等。
终止操作(Terminal Operations)
非短路操作:处理完所有数据才能得到结果。如collect()、count()、forEach()、forEachOrdered()、max()、min()、reduce()、toArray()等。
短路操作(short-circuiting)操作:拿到符合预期的结果就会停下来,不一定处理完所有数据。如anyMatch()、allMatch()、noneMatch()、findFirst()、findAny() 等。
流的执行顺序是一个元素会把流执行到底,并不是一个环节全部收集后再一起执行下一环节
源码分析
Iterator,Spliterator
Iterator
Java 8中为Iterator新增加一个缺省方法forEachRemaining(Consumer<? super E> action)。这个