目录
1. pipeline head初始化,直接传sourceSpliterator
pipeline head初始化,传sourceSupplier
封装collector变成terminalOp,最终层层委托封装给collector
case 使用
用来debug学习用 ( 熟悉类图的前提是要了解动态流程,本质的数据流. 类都是为了复用抽象使用的. case越多,使用场景越多, 抽象会越多.)
String[] strings = {"Hello", "World"};
List list = Arrays.asList(strings);
Stream stream = list.stream();
Object collects = stream.map(str -> {
return ((String) str).split("");})
.flatMap(str-> {
return java.util.Arrays.stream((String[]) str);})
.collect(Collectors.toList());
System.out.println(JsonUtils.toJSONString(collects));
输出:
["H","e","l","l","o","W","o","r","l","d"]
stream原理
stream翻译就是 流 , 有n个pipeline组成 + 一个多线程迭代器Spliterator (splIter Iterator 分割迭代器) . 如下图, list.toStream() ,最终调用如下方法, 生成一个pipeline head.
jdk8中Spliterator的作用
pipeline家庭
单个pipeline构造方法和重要字段:
1. pipeline head初始化,直接传sourceSpliterator
pipeline head初始化,传sourceSupplier
初始化时,source是自己, sourceSupplier是传过来的 suppiler,提供动态生成 spliterator
构造中间stage pipeline
构造pipeline链
当前的this传递给新的pipeline 即 statelessOp .
pipeline触发
String[] strings = {"Hello", "World"};
List list = Arrays.asList(strings);
Stream stream = list.stream();
Stream stream1 = stream.flatMap(str ->
{
return ((String) str).split("");
});
Object collects = stream1
.collect(
Collectors.toList()
);
System.out.println(JsonUtils.toJSONString(collects));
封装collector变成terminalOp,最终层层委托封装给collector
获取源迭代器
封装sink
通过terminalOp(实现类是ReduceOp,ForEachOp,同时也是AccumulatingSink子类)的makeSink接口生成ReducingSink内部类 [其中ReduceOp和ReducingSink都是AccumulatingSink子类,为啥要托管给ReducingSink内部类]
生成sink链(consumer链)
利用pipeline链生成sink链, 将terminalOp的操作,层层传递给下游,从最上游开始执行.
接上图
执行
每个accept都是每个pipeline生成的sink的accept实现. 见上图 flatMap生成的匿名内部类.
抛异常分析
flat直接想转换成List
String[] strings = {"Hello", "World"};
List list = Arrays.asList(strings);
Stream stream = list.stream();
Stream stream1 = stream.flatMap(str ->
{
return ((String) str).split("");
});
Object collects = stream1
.collect(
Collectors.toList()
);
System.out.println(JsonUtils.toJSONString(collects));
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.util.stream.Stream
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
原因是flatmap要求function返回的对象必须是stream.
flatMap其他实例文章 java8中 map和flatmap的共同点和区别,以及两者的实例解析
附录:
flatMap时的两个new, 内存代码 和 ddd 领域设计相似点