Java 8 Stream 中的一些有状态中间操作仍然是懒惰寻找的



在Java 8 Stream API中,对中间(无状态(操作(如filter,map和peek(的描述被提及为惰性查找 - 这意味着当终端操作需要时,它将逐个元素地处理。

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

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

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

这引发了我一个问题(可能是愚蠢的或误解了懒惰的寻求与渴望(这些"有状态的中间操作"仍然是懒惰的寻找?

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

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

这正是它所说的意思。某些有状态操作可能会处理整个输入。如果你往上看几段,你会看到以下内容(强调添加(:

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

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

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

最新更新