从java 8以后,jdk底层新增了Stream API,使我们写出更简洁、干净的代码来对集合、数组等进行操作,先简单介绍下流的几个概念:
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
- Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
- 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
下面首先看一下jdk源码中如何实现返回流对象(Stream),打开Collection接口源码,可以Collection增加了以下两个方法:
其中可以看到,多出了我们经常使用的两个方法,stream和parallelStream方法,都返回了该集合的Stream对象(该接口中包含了许多操作流的方法,这里不一一列举,详细用法看API,在这里主要阅读源码理解其实现),一看名称,就能大概猜出来其中一个是串行流,另一个是并行流。并且接口中给了这两个方法的默认实现。其中采用了StreamSupport的stream方法,这个类也是java 8新增的一个底层创建和操作Stream的工具类。
那这个StreamSupport中又是做了些啥呢?继续跟代码下去就会发现,它根据提供的元素分割器(Spliterator)和是否并行创建了一个Stream的实现类,ReferencePipeline的静态内部实现类Head类,这个类