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本身实际上是一个工厂。【在之后也会研读它里面的源码滴】
java8学习之Collector源码分析与收集器核心的更多相关文章
- java8学习之groupingBy源码分析
继续接着上一次[http://www.cnblogs.com/webor2006/p/8366083.html]来分析Collectors中的各种收集器的实现, 对里它里面有个groupingby() ...
- java8学习之Stream源码分析
上一次已经将Collectors类中的各种系统收集器的源代码进行了完整的学习,而在之前咱们已经花了大量的篇幅对其Stream进行了详细的示例学习,如: 那接下来则通过源代码的角度来对Stream的运作 ...
- Java8集合框架——LinkedList源码分析
java.util.LinkedList 本文的主要目录结构: 一.LinkedList的特点及与ArrayList的比较 二.LinkedList的内部实现 三.LinkedList添加元素 四.L ...
- Zepto源码分析(一)核心代码分析
本文只分析核心的部分代码,并且在这部分代码有删减,但是不影响代码的正常运行. 目录 * 用闭包封装Zepto * 开始处理细节 * 正式处理数据(获取选择器选择的DOM) * 正式处理数据(添加DOM ...
- springMVC源码分析--HandlerInterceptor拦截器调用过程(二)
在上一篇博客springMVC源码分析--HandlerInterceptor拦截器(一)中我们介绍了HandlerInterceptor拦截器相关的内容,了解到了HandlerInterceptor ...
- ThreeJS 物理材质shader源码分析(顶点着色器)
再此之前推荐一款GLTF物理材质在线编辑器https://tinygltf.xyz/ ThreeJS 物理材质shader源码分析(顶点着色器) Threejs将shader代码分为ShaderLib ...
- kube-scheduler源码分析(2)-核心处理逻辑分析
kube-scheduler源码分析(2)-核心处理逻辑分析 kube-scheduler简介 kube-scheduler组件是kubernetes中的核心组件之一,主要负责pod资源对象的调度工作 ...
- Nginx学习笔记4 源码分析
Nginx学习笔记(四) 源码分析 源码分析 在茫茫的源码中,看到了几个好像挺熟悉的名字(socket/UDP/shmem).那就来看看这个文件吧!从简单的开始~~~ src/os/unix/Ngx_ ...
- MQTT再学习 -- MQTT 客户端源码分析
MQTT 源码分析,搜索了一下发现网络上讲的很少,多是逍遥子的那几篇. 参看:逍遥子_mosquitto源码分析系列 参看:MQTT libmosquitto源码分析 参看:Mosquitto学习笔记 ...
随机推荐
- jinja2渲染使用
说明:通过jinja2渲染后只能打印出来效果,目前无法保存 例1:渲染 .j2 文件 1.安装jinja2模块 pip3 install jinja2 2.定义模板 说明:变量必须是小写,大写有的情况 ...
- java:LeakFilling (Linux)
1.Nosql 列数据库,没有update,非关系型数据库: 为了解决高并发.高可扩展.高可用.大数据存储问题而产生的数据库解决方案,就是NoSql数据库. NoSQL,泛指非关系型的数据库,NoS ...
- VM虚拟机网络设置
两台PC安装了虚拟机和XP,采用“桥接”模式,设置了两个虚拟机的地址为同网段.但发现飞Q可以联通,数据库无法连接,且ping不通. 解决: (1)将防火墙关闭. (2)通过“虚拟网络编辑器”将该网络桥 ...
- LinuxC/C++基础——引用
1.引用(Reference) 1.1引用的基本语法 引用是C++对C的重要扩充,也存在与其他一些编程语言中,并不是C++的发明.通过引用,C++增加了 另外一种给函数传递地址的途径,这就是按引用传递 ...
- Linux C/C++基础 文件(中)
1.ubuntu cat命令的实现 cat——查看或者合并文件内容 #include<stdio.h> int main(int argc,char* argv[]) { //1.打开文件 ...
- vue-teach
编译器的工作过程 http://www.ruanyifeng.com/blog/2014/11/compiler.html DNS 原理入门 http://www.ruanyifeng.com/blo ...
- 在C语言中函数及其调用过程
目录 函数 C语言中的变参函数 函数的本质是什么 内存区域的区分技巧 函数的调用过程 栈帧的概念 调用过程细节 按照约定传参 函数 如果一个函数有声明没实现,那么就会出现链接错误: 以上代码会出现链接 ...
- java并发学习资料
1.Java 并发编程知识梳理以及常见处理模式 https://github.com/Fadezed/concurrency 2.Java 高并发多线程编程系列 https://github.com/ ...
- [Python3] 038 函数式编程 偏函数
目录 函数式编程 之 偏函数 1. 关于强制类型转换 int 的补充 2. 利用 int 新建函数 3. functools.partial 函数式编程 之 偏函数 1. 关于强制类型转换 int 的 ...
- 说一下redis中5种数据类型的底层数据结构
前言: 阅读 redis设计与实现 一书的记录.未完待续... redis我们都知道有5种数据类型,分别是string,list,hash,set,zset,那么你知道它们的底层数据结构实现吗? ...