Java 8 Stream 中的一些 Stateful Intermediate Operations 仍然是 Lazy Seeking

Yuv*_* AK 1 java java-stream

在 Java 8 Stream API 中,过滤器、映射和查看等中间(无状态)操作的描述被称为“惰性查找”——意味着当终端操作需要时,它将逐个处理元素。

当终端操作命中时,操作是在流中的元素上独立实现的。

但是,当涉及到一些中间(有状态)操作(例如 sort() 、distinct() )时,需要在生成结果之前处理整个输入。

例如,在看到流的所有元素之前,无法对流进行排序产生任何结果 - 意味着在终端操作要求之前不独立地完成对所有元素的操作。

这引发了我一个问题(可能很愚蠢或误解了 Eager 的惰性查找),这些“有状态中间操作”仍然是惰性查找吗?

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

Avi*_*Avi 5

有状态操作可能需要在产生结果之前处理整个输入。例如,在查看流的所有元素之前,无法通过对流进行排序来产生任何结果。因此,在并行计算下,一些包含有状态中间操作的管道可能需要多次传递数据或者可能需要缓冲重要数据。

这正是它所说的意思。一些有状态操作可能会处理整个输入。如果您向上移动几段,您将看到以下内容(已添加重点):

中间操作返回一个新流。他们总是很懒;执行诸如filter()之类的中间操作实际上并不执行任何过滤,而是创建一个新流,该流在遍历时包含与给定谓词匹配的初始流的元素。直到执行了管道的终止操作后,才开始遍历管道源。

所以,是的,他们很懒。如果您调用sortStream 并且从不调用终端操作,则实际上不会sort在Stream 上进行工作。这就是懒惰的意思。但是,一旦在流上调用终端操作,类似的操作将在生成结果之前对整个输入进行操作。这使得此类操作对于并行化和短路操作来说非常糟糕,否则这些操作可能会在产生值之前仅处理一小部分输入。需要明确的是:sort

  • Stream 上的短路操作在生成值之前可能仅处理输入的一小部分。
  • Stream 上的惰性操作不会触发在该流上完成的工作,直到在所述 Stream 上调用终端操作为止。
  • 中间操作总是偷懒的。