Stream流
管道
管道是具体的实现,流只是我们对管道抽象出来的一个接口;流中的filter,map等方法都是在jvm中实现的,我们的数据不会存储在stream中他还是在源的位置; 我们的数据是一个个进行处理的就是一个个通过我们的聚合操作;
数据流动示意图
- [数据源] → [流管道] → [结果]
- (集合/数组/生成器) (操作链) (收集器/消费)
数据存在位置的阶段变化
| 操作阶段 | 数据主要位置 | 是否存储数据 |
|---|---|---|
| 创建流(.stream()) | 原始集合/数组/生成器 | 是 |
| 中间操作期间 | 正在管道中流动的元素 | 否(瞬时状态) |
| 收集操作开始后 | 收集器创建的容器(ArrayList等) | 是 |
流水线惰性执行:我们进行中间操作的时候没有执行对应的方法而是把方法存储下来直到终端操作在统一执行;
- 操作步骤被记录而非立即执行
- 类似构建"菜谱"而非实际烹饪
- 终端操作相当于"开始烹饪"指令
如何获取Stream流
集合中只有Collection中,能够直接生成流,Map中的集合需要转化成Collection里面的才能够变成流;
Stream流的中间聚合操作
逻辑上:每一步聚合操作都创建了一个新的Stream流;
实际运行中:每一个元素都是逐个通过管道无论是顺序流还是并行流;
-
顺序流:
- 逻辑上是元素逐个通过整个管道
- JVM可能优化为融合操作的单次循环
-
并行流:
- 元素被分块由不同线程处理
- 需要合并的操作会聚合部分结果
-
特殊操作:
- 短路操作会提前终止
- 有状态操作需要收集数据
Stream的终结聚合操作;
Stream流聚合操作和迭代器的区别
区别1:流使用的是内部迭代;迭代器用的是外部排序器
区别2:流处理的是流里面的元素;迭代器处理的是集合中的元素
区别3:流中的聚合操作中有大量的lambda表达式作为参数