- 持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
前言
在jdk1.8加入了stream流后我们在处理列表数据的时候减少了很多重复繁杂的逻辑处理,但是列表是怎么做到使用steam流来处理数据的就需要来看一下它的实现原理了。
List
这里使用List举例来看一下,先创建List并使用stream方法
public static void main(String[] args) {
List<User> list = new ArrayList();
list.stream();
}
进入到stream到方法
可以看到是Collection接口定义的默认方法,如果子类不重写会走上图的执行逻辑,这样只要是Collection接口的子类都无需实现此方法,在List跟AraayList的源码里并没有发现设计Stream的方法
ArrayList的类图
Stream的流程
1. Stream对象
在源码中Stream的对象是直接通过StreamSupport.stream这个方法获取的,方法入参是一个方法跟false,接下里看StreamSupport.stream
1.1 StreamSupport.stream
在这个方法内先判断spliterator是否为空,为空直接抛异常,后续的流程就在ReferencePipeline的静态内部类Head中
1.2 ReferencePipeline.Head
Head是ReferencePipeline的静态内部类并且是它的子类,在这里看到后续逻辑指向了它的父类ReferencePipeline
跟到父类发现还是指向的父类,看一下类图
在类图中ReferencePipeline这个类继承类AbstractPipeline这个类,并且继承了Stream,这就解释了为什么上面的返回是返回的这个类,但是初始化操作是它的父类AbstractPipeline做的,我们来看一下
1.3 AbstractPipeline
这是AbstractPipeline的构造函数,也是这一步完成了Stream对象的创建
Stream对象
列表在进行.stream的时候是获得了一个Stream对象,对象的属性如下
像我们在使用筛选时的filter,统计时的count,转结构时的collect都在此进行了定义,具体的实现就交给了它的实现类,我们使用List的stream默认是使用的实现类ReferencePipeline,来看ReferencePipeline是怎么实现的后续处理
ReferencePipeline
collect
collect是经常使用的要进行数据格式转换的方法,看看在ReferencePipeline是怎么具体实现的