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学习笔记 ...
随机推荐
- delphi怎么一次性动态删除(释放)数个动态创建的组件?
比如procedure TForm1.Button1Click(Sender: TObject);vari:Integer;lbl: TLabel;beginfor i:=1 to 3 dobegin ...
- Head First HTML 与 CSS 学习笔记
总的来说,这本书作为入门HTML和CSS还是不错的,讲解生动有趣,这也是Head First系列书籍的特点.缺点就是讲解的不够全面~ 第三章 一般来讲,如果要引用一段或者多段文字, 就要使用<b ...
- Python 导入文件问题
1.同级目录下调用 若在程序 testone.py 中导入模块 testtwo.py , 则直接使用 [import testtwo 或 from testtwo import *] 2.调用子目录 ...
- golang可见性规则(公有与私有,访问权限)
Go语言没有像其它语言一样有public.protected.private等访问控制修饰符,它是通过字母大小写来控制可见性的,如果定义的常量.变量.类型.接口.结构.函数等的名称是大写字母开头 ...
- Qt输出中文乱码的问题
/* 我遇到的情况: 文件编码为UTF-8.程序输输出中文位乱码. 解决方案: 1. 工具->选项->环境->语言: Chinese 2. 选项->文本编辑器->行为-& ...
- python基础 --- 难点重点
循环嵌套 # 打印九九乘法表 for row in range(1,10): # 行与列相乘 for col in range(1,row+1): print(col,'*',row,'=',row ...
- Python面试简介及并行并发
今天的分享内容大体如下: 一. 面试 1. 什么是面试 2. 优秀的面试 二. Python综述 1. Python设计哲学及版本变迁 2. Python发展现状及其他语言使用场景 3. GIL 4. ...
- Linux 基础整理
Linux系统的启动过程大体上可分为五部分:内核的引导:运行init:系统初始化:建立终端 :用户登录系统. 用户登录 Linux的账号验证程序是login,login会接收mingetty传来的用户 ...
- webdriervAPI(操作cookie)
from selenium import webdriver driver = webdriver.Chorme() driver.get("http://www.baidu.co ...
- java.io.IOException 断开的管道 解决方法 ClientAbortException: java.io.IOException: Broken pipe
今天公司技术支持的童鞋报告一个客户的服务不工作了,紧急求助,于是远程登陆上服务器排查问题. 查看采集数据的tomcat日志,习惯性的先翻到日志的最后去查看有没有异常的打印,果然发现了好几种异常信息,但 ...