zoukankan      html  css  js  c++  java
  • java8学习之Stream深度解析与源码实践

     继续对流进行学习,首先先说明一下流的特点:

    1、Collection提供了新的stream()方法。

    2、流不存储,通过管道的方式获取值。

    3、本质是函数式的,对流的操作会生成一个结果,不过并不会修改底层的数据源,集合可以作为流的底层数据源。
    其中需要注意标红的说明,也就是说对于流操作它的源数据是不会被更改的,另外还有一点需要有一个认知:对于一个流可能有若干个中间操作,对于这些操作并非降低了整体的执行性能,反而会有提升,比如说增加了三个中间操作,可能感受会有三次循环,但是实际并非是咱们想象的这样,这个随着流的不断深入就会体会到这点的。

    4、延迟查找,很多流操作(过滤filter、映射map、排序sort等)都可以延迟实现。

    接着再用代码来进行操练,首先构建一个Stream对象,这里用一个集合的方式构建,然后将它转换数组,如下:

    下面具体看一下该方法的定义:

    而IntFunction的接口原型如下:

    那这个参数如何写呢?当然可以用Lambda表达式啦,那具体如何表示呢?看下面:

    其实对于这个toArray()参数还可以改用方法引用,那如何写呢?

    接下来想办法将Stream转换为一个List,如何搞呢?

    所以转换如下:

    初略查看一下上面用到的Collectors类,发现其实它是Java1.8针对集合提供的一个工具类,里面包含若干个实现的工具方法,如下:

    那看一下用到的toList()方法的实现:

    而回到Stream.collect()方法,它还有另外一个比较复杂的方法重载,如下:

    点进去查看一下该方法的定义:

    是不是跟第一个collect()方法中使用的Collectors.toList()方法的具体实现中CollectorImpl中的参数一样?既然用stream.collect(Collectors.toList())能达到转换成List的目的,还研究第二种比较复杂重载的stream.collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)干嘛呢?因为要想搞清楚stream.collect(Collectors.toList())就必须理解这种比较复杂的collect(),因为Collectors.toList()最终的实现就是跟比较复杂的collect()的实现类似,所以说接下来好好理解一下这个比较复杂的方法,确实是不太好理解,先读下它的javadoc:

    那什么叫"mutable reduction可变的汇聚"呢?接着看解释:

    不晓得说的是什么意思,下面有个例子对其进行说明:

    那如何调用这种复杂的collect()方法来实现stream.collect(Collectors.toList())同样的效果呢?实现过程会要复杂很多,但是这个复杂的过程是对其内部了解起到很大的作用,所以有必要折腾一下:

    首先第一个参数传递的它:

    而Supplier接口的原型是:

    因为这个参数是作为最终方法的结果,所以很显然最终应该返回一个ArrayList,所以传参可以这么搞:

    接着再来传第二个参数,看下它的原型:

    那什么叫累加器呢?在方法注释上也可以看出:

    而BiConsumer的接口原型如下:

    那这个参数可以这样来传:

    还有最后一个参数,它也是BiFunction类型的,如下:

    这里先直接上代码,之后再来理解它:

    那对于第三个参数的合并器如何来理解呢?其实就是将上一次添的加结果集最终合并到要返回的结果集当中,其中theList1则为要返回的结果集,theList2为上一次累加的结果集,比较难以理解。

    其实对于上面的实现还可以用方法引用的方式来代替,这里打算改用LinkedList再改用方法引用去弄,传第一个参数既要返回的结果:

    接着传第二个累加器参数,需要接收两个参数,无返回值,这时可以看一下LinkedList.add()方法,如下:

    所以第二个参数可以这样写:

    接着第三个参数,由于跟第二个参数类型一样,类似的对于LinkedList中有一个addAll方法:

    依然可以用方法引用嘛,如下:

    好了,接下来再回过头来继续读一下collect()方法:

    接下来看一下参数的说明:

    再结合咱们的代码来说:

    接着再回到stream.collection(Collectors.toList())这个简单的重载方法,看一下它系统的实现:

    所以虽然复杂的这个重载方法理解起来比较麻烦,但是这个麻烦是值得滴,另外还有一个原因,因为stream.collection(Collectors.toList())只返回的是一个ArrayList,如果想要返回其它类型的集合如咱们已经实现的LinkedList,那就必须理解复杂的collect()。

  • 相关阅读:
    [转载]注解
    Spring可扩展的XML Schema机制 NamespaceHandlerSupport
    jvm中的年轻代 老年代 持久代 gc ----------转载
    反射原理
    舍入误差
    mysql突然宕机后事务如何处理?
    redis为什么设计成单线程并且还这么快?
    mysql架构学习
    用户级线程和内核级线程的区别
    G1垃圾收集器
  • 原文地址:https://www.cnblogs.com/webor2006/p/8290226.html
Copyright © 2011-2022 走看看