- 流
- 集合与流
- 流操作
一、流
概念:
从支持数据处理操作的源生成的元素序列
元素序列:流提供了一个接口,可以访问特定元素类型的一组有序值。何谓有序,就是说我们一般是按顺序取用值,而不是随机取用的。
源:流会使用一个提供数据的源,如集合、数组、输入/输出资源;从有序集合生成流,会保留原有顺序;由列表生成的流,七元素顺序与列表一致
数据处理操作:流的数据处理功能支持类似数据的操作,以及函数式编程语言中的常用操作,流操作可以顺序执行,也可以并行执行
流操作的两个重要特点:
1.流水线:很多流操作本身返回一个流,这样多个操作就可以链接起来,形成一个流水线。
2.内部迭代:与使用迭代器显式迭代的集合不同,流的迭代操作是在背后进行的。
好处:
1) Stream API可以在背后进行多种优化
2) Stream API可以决定并行运行你的代码
PS:这让我想起了Spark的处理方式,只有写出数据的时候,才会真正计算,并且会自动优化我们的代码,执行顺序。
二、流与集合
相同点:
Java现有的集合概念和新的流概念都提供了接口,来配合代表元素型有序值的数据接口。所谓有序,就是说我们一般是按顺序取用值,而不是随机取用的。
不同点:
1、流和集合之间的差异在于什么时候进行计算
集合:
集合是数据结构,主要目的是以特定的时间/空间复杂度存储和访问元素,它包含数据结构中目前所有的值(集合中的每个元素都得先算出来才能添加到集合中,你可以往集合中添加或者删除元素,但不管何时,集合中的每个元素都是存放在内存中,元素得先算出来才能存放在集合中)
流:流是在概念上固定的数据结构(我们不能添加或者删除元素),其元素是按需计算的。换句话说,流好像是一个延迟创建的集合:只有在消费者要求的时候才会计算值
2、流只能遍历一次
和迭代器类似,流只能遍历一次,遍历完之后,流就被消费掉了。如果多次消费,会抛出java.lang.IllegalStateException :流已被操作或关闭
3、外部迭代与内部迭代
集合使用迭代器,需要我们自身去做迭代,如使用(for-each)或者直接使用for-each背后的iterator。
流使用Streams库的内部迭代,其可以自动选择一种适合我们硬件的数据表示和并行实现
即:集合的迭代,需要我们关心并实现如何迭代,如何解决并行问题,而流的内部迭代我们只需要关心做什么操作,而不需要关心如何实现。
三、流操作
流的操作分为两种:中间操作、终端操作
中间操作返回另外一个流,可以让多个操作连接成一个流水线。流水线上除非触发一个终端操作。否则中间不会执行任何操作。中间操作一般都可以合并起来,在终端操作时一次性全部处理。
终端操作会从流的流水线生成结果,其结果是任何不是流的值,如List、Integer、甚至void