java.util.stream.Stream是从支持数据处理操作的源生成的元素序列。 流可以让用户以声明性的方式处理数据集。
元素序列:流可以访问特定元素类型的一组有序值。
源:提供数据的源。
声明性方式是说明想要完成的操作,而不是说明如何实现该操作。
流与集合
Java中的集合是存储数据的容器,每次对数据进行处理需要用户迭代遍历,显式实现对数据的操作,同时为处理大量数据,用户需要进行并行处理,而并行代码的编写更为复杂。java8引入了流来解决集合这两个问题。
集合的核心是数据,流的核心是计算。
计算与创建的先后
集合与流的差异在于集合与流的创建与计算时间先后不同。
集合先创建,再对其中的数据进行计算。流的元素是通过计算,按需生成,延迟创建,与下一步操作之间是生成者-消费者的关系,类似于python的生成器。
流的遍历只能进行一次。
迭代方式
集合与流的另一个差异在于它们迭代方式不同。
集合需要用户控制迭代的流程,而流将迭代实现在库的内部,用户只需告诉流需要进行什么操作。
需要用户自己进行迭代的方式叫做外部迭代。
用户无需进行迭代操作的方式叫做内部迭代。
内部迭代时,项目可以透明地并行处理,或者用更优化的顺序进行处理。要是用Java过去的那种外部迭代方法,这些优化都是很困难的。
流的介绍
流的特点
- 许多流的操作会返回流,因而可以进行链式处理。
- 流的迭代是隐式的内部迭代,无需用户关心迭代的实现。
流操作
Stream接口定义了许多操作,依据该操作是否返回流将这些操作分为中间操作和终端操作。
可以连接起来的流操作称为中间操作,关闭流的操作称为终端操作。
List<String> selectedPeople = people.stream()
.filter(person -> person.getTel().length()>10)
.map(Person::getName)
.limit(3)
.collect(Collectors.toList());
-
中间操作
除非流水线上触发一个终端操作,否则中间操作不会执行任何处理。
-
终端操作
终端操作会从流的流水线生成结果,其结果是任何不是流的值。
流的使用
流的使用一般包括三件事:
- 一个数据源(如集合)来执行一个查询
- 一个中间操作链,形成一条流的流水线
- 一个终端操作,执行流水线,并能生成结果