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学习笔记 ...
随机推荐
- SQL Server 等待统计信息基线收集
背景 我们随时监控每个服务器不同时间段的wait statistics ,可以根据监控信息大概判断什么时候开始出现异常,相当于一个wait statistics基线收集,还可以具体分析占比高的等待类型 ...
- DELPHI 通用的数据记录复制过程
//表名,关键字段名,单条内容的SQL语句,产生新记录的值 function Tfrmdmmain.CopyTbale(const tablename, fileldname, swhere, new ...
- YII :将oracle中timestamp 字段正常显示在页面中
'value'=>'DateTime::createFromFormat("d#M#y H#i#s*A", $data["START_TIME"])-&g ...
- java数据结构之ArrayList
一.ArrayList源码注释 /** * ArrayList源码分析,jdk版本为1.8.0_121 */ public class ArrayList<E> extends Abstr ...
- python网络编程(Socket、TCP、UDP)
Socket 是网络编程的一个抽象概念,通常我们用一个Socket表示 "打开了一个网络链接",而打开一个Socket 需要知道目标计算机的IP 地址和端口号,再指定协议类型即可. ...
- C++实现生产者和消费者
传统的生产者消费者模型 生产者-消费者模式是一个十分经典的多线程并发协作的模式,弄懂生产者-消费者问题能够让我们对并发编程的理解加深.所谓生产者-消费者问题,实际上主要是包含了两类线程,一种是生产者线 ...
- Android开发实例 Unity显示Toast
Android中的Toast是一种简易的消息提示框. 当视图显示给用户,在应用程序中显示为浮动.和Dialog不一样的是,它永远不会获得焦点,无法被点击.用户将可能是在中间键入别的东西.Toast类的 ...
- C# AE 通过要素类工作空间将shp路径string类型对象转换为IFeatureClass;
IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactoryClass();//打开shapefile工作空间openFile ...
- 自然数幂和(递推式k^2方法)
先用这个方法顶一下!
- java.sql.SQLException: Access denied for user 'root'@'10.10.7.180' (using password: YES)
1.刚开始连接数据库提示是: java.sql.SQLException: Access denied for user 'root'@'10.10.7.180' (using password: N ...