zoukankan      html  css  js  c++  java
  • java8学习之Collector源码分析与收集器核心

    之前已经对流在使用上已经进行了大量应用了,也就是说对于它的应用是比较熟悉了,但是比较欠缺的是对于它底层的实现还不太了解,所以接下来准备大量通过阅读官方的javadoc反过来加深对咱们已经掌握这些知识更加深层次的理解,这个阅读会是一个比较枯燥的,但是它的价值是非常非常大的,也就是要达到知其然知其所以然的目的。

    这里先以一个咱们之前用过的例子为例,以它做为咱们分析源码的一个入口,新建一个学生类:

    然后生成集合:

    然后干一个很无聊的操作:用stream再将它转换成List并打印,如下:

    为什么要举这个重复的例子呢?这时因为要重点看一下stream().collect()方法:

    那这个方法之前不已经大量使用过了么,有啥好看的,那这样来问:它底层的实现机制是怎么样的你知道么? 我想可能就得哑口无言了,该方法在Stream中来说是一个极其重要的方法,如果理解了stream.collect()方法及它里面的参数,对于咱们编写正确的城市是极为有帮助的,下面继续来说一个例子,来计算一下该集合的个数,当然直接用集合的size()方法就可以直接获得,不过这里是采用流的方式去获取,如下:

    还有另外一种通过流获取元数个数的方法:

    说明在Java8中通常一个实现可以有几种方式去实现,比如之前的map和mapToInt(),之前也强调过选择的原则是越具体的实现越好,如mapToInt()就比map()要好,因为可以避免拆装箱。而对于咱们这个例子我也不晓得哪个更加具体,我觉得第二种使用起来更加简单。

    举了简单的例子之后,接下来就得把焦点放在collect()方法上啦,而它可以翻译为"收集器",点击看一下它的方法定义:

    接下来就是重点去分析一下Collector,它是一个接口,而对于咱们已经在使用的Collectors中的常用方法都是返回这个接口,如这个例子中使用的toList(),counting()方法,如下:

    所以说Collector这个接口在Stream中是何等的重要,之所以举这么简单的例子也就是为了引出它,接下来要做的事就是彻底的研究透它,对于官方的Javadoc一行一行的理解,先打开它的源码看一下它的定义:

    而对于这个接口官方给它加了详细的描述,所以接下来了解它从一行行读javadoc开始:

    这句描述非常的重要,之后待理解了Collector之后可以回头再来体会下它,其中:

    其中串行流(stream())与并行流(parallelStream())这个之前咱们已经使用过了,需要强调一点的是:并非并行流就一定比串行要快,因为并行是涉及到CPU切换的需要开销的,需要根据实际的场景针对性的去选择。

    接下来继续往下看:

    这Collectors不就是咱们在collect()方法中一直在用的么?

    实际上它里面提供的方法都是对咱们看的这个Collector接口的实现,下面继续:

    可以看一下这个函数在接口中的定义:

    意思就是说咱们最终要返回什么容器,则由它来创建。

    其中它返回的是BiConsumer,看下它的接口原型:

    查看一下它的函数定义:

    其返回一个BinaryOperator,这个咱们用过,回顾下接口原型:

    接收相同类型的两个参数,返回一个相同类型的结果。

    看一下finisher()方法的定义:

    这里只要知道Collector中包含比较重要的四个方法:supplier()、accumulator()、combiner()、finisher(),并对其大概知道其作用就成,之后会彻底理清这些函数据的作用滴。

    这次暂且先读到这,下次继续~

    从读javadoc中将要点总结如下:

    1、stream.collect()名为收集器。

    2、Collector作为collect方法的参数。

    3、Collector是一个接口,它是一个可变的汇聚操作,将输入元素累积到一个可变的结果容器中;它会在所有元素都处理完毕之后,将累积的结果转换为一个最终的表示。【这是一个可选的操作】;它支持串行与并行两种方式执行。

    4、Collectors本身提供了关于Collector的常见汇聚实现,Collectors本身实际上是一个工厂。【在之后也会研读它里面的源码滴】

  • 相关阅读:
    【Linux编程基础】构建Linux 库文件
    【Linux调试技术】查看数据
    【C++学习】复制构造函数和赋值运算符根本的不同
    【C++学习】显式构造函数
    【C++学习】函数对象和Lambda表达式
    【C++学习】类初始化列表的分析总结
    【Linux开发基础】Linux守护服务进程(Daemon service)编程
    【编程小结】C++和Java 的缺省初始化问题
    SQL查询金额去掉小数点后面的零
    SQL自定义函数split 将数组(分隔字符串)返回阵列(表)
  • 原文地址:https://www.cnblogs.com/webor2006/p/8311074.html
Copyright © 2011-2022 走看看