一。 进入stream()方法
可以很清楚的看到 stream()的方法来自Collection这个顶级接口,这意味着java里所有的实现类都能使用流,也意味着,只有它的子类可以使用流。
此时我们发现stream()里面有个spliterator()方法
spliterator()方法:
放入了this,说明将集合数据的放入了,此时就拿到了数据对象的引用
进入IteratorSpliterator类后,我们发现他是Spliterators的内部类
进入StreamSupport.stream(spliterator(), false);
此时因为我使用的是ArrayList,所以调用的是ArraySpliterator,这一步得出标志
进入head
创建一个状态流
创建一个流管道头的构造函数
sourceOrOpFlags标志位
到此,流创建完成。其实在底层本来就是字节流, 与其说创建,不如说是封装了一下,添加了各种标识,方便后面方法处理。
二 。我们使用一下案例进行后续分析:
我们接下来进入sorted():发现这个sorted进入了第一节提到的ReferencePipeline
进入SortedOps.makeRef(this):
upstream参数就是管道,为什么要使用管道?因为管道中有 处理的数据(第一节中封装所做的标志)
进入super后会发现又回到了ReferencePipeline
StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED 这个就是排序标志
经历这些类之后,发现:压根就没有对流进行排序(从头到尾到没有看见有关排序的方法),只是放置了一个排序标志位
第三步进入forEach
进入黄字sourceSpliterator方法,最终会执行StreamOpFlag.combineOpFlags(terminalFlags, combinedFlags)
combinedFlags标志正是我们第2节 传入的
进入后会发现
将标志进行组合
进入 terminalOp.evaluateSequential(
一个是管道执行接口,一个是分割接口,都是顶级接口
在一个 ForEachOps子类中
进入wrapSink方法
【注:Sink 是Consumer的扩展,用于通过流管道的各个阶段来执行值,以及用于管理大小信息,控制流等的其他方法。】
进入opWrapSink
进入copyInto
结果发现begin只是创建了一个object数组
对给定的参数执行此操作。
seen是一个set
发现了一个神奇的方法Arrays.sort(array, 0, offset, comparator); 是不是意味着,这里我们才开始真正的排序操作? 答案:是。
可以看到我们的数组此时任然是无序的
数组有序了