Java 惰性流,用户希望处理满足条件所需的最小数量的流元素。流是惰性的,在达到终止条件前不会处理元素,达到终止条件后逐个处理每个元素。如果遇到短路操作,那么只要满足所有条件,流处理就会终止。读者在第一次接触流处理时,很容易认为流处理的效率不高。
Java 惰性流 问题描述
用户希望处理满足条件所需的最小数量的流元素。
Java 惰性流 解决方案
流是惰性的,在达到终止条件前不会处理元素,达到终止条件后逐个处理每个元素。如果遇到短路操作,那么只要满足所有条件,流处理就会终止。
Java 惰性流 具体实例
读者在第一次接触流处理时,很容易认为流处理的效率不高。如例 3-65 所示,我们将 100 到 200 之间的所有整数倍增,然后找出能被 3 整除的第一个整数。
例 3-65 将 100 到 200 之间的所有整数倍增,再找出能被 3 整除的第一个整数
➊ 打印 Optional[204]
如果不了解流处理的机制,读者可能认为上述代码做了不少无用功:
- 创建 100 到 199 之间的整数(100 次操作)
- 将每个整数倍增(100 次操作)
- 校验每个整数能否被 3 整除(100 次操作)
- 返回结果流的第一个元素(1 次操作)
那么,既然满足要求的第一个值为 204,为什么还要处理所有其他的数字呢?
不要误会,流处理的机制并非如此。流是惰性的,在达到终止条件前不会处理元素,达到终止条件后才通过流水线逐一处理每个元素。为说明这一点,例 3-66 对代码进行重构,以便读者观察每个元素通过流水线时的情况。
例 3-66 对每个流元素进行显式处理
❶ 用于倍增(并打印)的方法引用
❷ 用于对 3 取模(并打印)的方法引用
例 3-66 的输出如下:
在本例中,100 被映射到 200,它未通过筛选器,流移至 101;101 被映射到 202,它同样未通过筛选器;下一个值 102 被映射到 204,它能被 3 整除,因此通过筛选器。流处理在仅处理三个值后即告终止,一共进行了 6 次操作。
这是流处理相对于直接处理集合的最大优点之一。对集合而言,必须执行完所有操作才能进行下一步操作。对流而言,各种中间操作构成了一条流水线,但流在达到终止操作前不会处理任何元素,达到终止操作后只处理所需的值。
流处理并非在任何情况下都有意义:如果进行任何状态操作(如排序或求和),就不得不处理所有值。但是,如果无状态操作后跟一个短路终止操作,流处理的优点还是很明显的。