java stream 原理 flatMap 原理 ,案例Exception分析

目录

case 使用

输出:

stream原理 

jdk8中Spliterator的作用

pipeline家庭

单个pipeline构造方法和重要字段:

1. pipeline head初始化,直接传sourceSpliterator

pipeline head初始化,传sourceSupplier

构造中间stage pipeline

构造pipeline链

pipeline触发

封装collector变成terminalOp,最终层层委托封装给collector

获取源迭代器

封装sink

生成sink链(consumer链)

执行

抛异常分析

附录:


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

获取源迭代器

jdk8中Spliterator的作用

封装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 领域设计相似点

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值