流的结构

所有流计算都有一种共同的结构:

  • 一个流来源(Collection::stream, Arrays::stream, Stream::generate)
    • 流的来源大部分是集合,也可以从数组生成器工厂等来源。
  • 零或多个中间操作
    • 将一个流转换成另一个流。
    • 惰性:调用中间操作只会设置流管道的下一个阶段,不会启动任何操作。
    • 状态性
      • 有状态:合并以前看到的影响其他元素处理的元素状态。(sorted, distinct)
      • 无状态:独立处理每个元素。(filter, map)
  • 一个终止操作(toArray, reduce, collect)
    • 生成一个结果或副作用。
    • 终止后如果要再次遍历同一个数据集,需要设置一个新的流管道。

流的注重点:计算

计算 计算 计算 终止

—————————————> 一轮 -> 下一个元素

—————————————> 又一轮 -> 下一个元素

—————————————> 再一轮 -> 下一个元素

惰性

对于流,只有 终止 操作是 急切 的;其他操作 都是 惰性 的。流操作表示其输入(也是流)上的功能转换,而不是数据集上的突变性操作(过滤一个流会 生成一个新流,新流的元素 是输入流的子集,但没有从来源删除任何元素)。

短路

短路类似于 C++/Java 中的 if 中带有 &&的判断。

操作融合

在数据上的一轮中执行多个操作。“深度优先”,提高数据在缓存中的利用率(数据更“热”),提升性能。

并行性

并行性并不是高性能的原因。并行执行可能比顺序执行更快、一样快或更慢。 最好先从顺序流开始

lambda的限制

互不干扰

它们不会修改流来源。

无状态

它们不会访问(读或写)任何可能在流操作寿命内改变的状态。

关于副作用

最好是无副作用:它们不会突变任何基于堆的状态或在执行过程中执行任何 I/O。

否则,会进行协调,以确保这些副作用是线程安全的。同时,副作用可能被优化掉不执行。