我发现了一个关于peek方法的Java8StreamAPI的测试,如下所示
Arrays.asList("Fred", "Jim", "Sheila")
.stream()
.peek(System.out::println)
.allMatch(s -> s.startsWith("F"));输出是
Fred
Jim我搞不懂这条小溪是怎么工作的?我的预期结果应该是
Fred
Jim
Sheilapeek()方法是一个中间操作,它处理Stream中的每个元素。有人能解释一下吗。
发布于 2020-03-03 01:22:56
这是一种称为短路的流优化。本质上,所发生的事情是allMatch阻止在流上执行不必要的中间操作,因为当知道最终结果时,执行这些操作没有意义。
就好像这事发生了:
take"Fred"
peek("Fred")
evaluate("Fred".startsWith("F"))
decide whether the result of allMatch() is known for sure: Not yet
take"Jim"
peek("Jim")
evaluate("Jim".startsWith("F"))
decide whether the result of allMatch() is known for sure: Yes当计算"Jim".startsWith("F")时,allMatch(s -> s.startsWith("F"))的结果是肯定的。不管在"Jim"之后出现了哪些值,我们知道所有的值都以"F“开头,是false
这不是特定于peek/allMatch组合,有多个中间和终端短路操作。包裹的文档状态:
此外,一些操作被认为是短路操作.中间操作是短路的,如果当呈现无限输入时,它可能产生有限的流。如果在无限输入的情况下,终端操作在有限的时间内终止,则终端操作是短路的。在管道中进行短路操作是处理无限流在有限时间内正常终止的必要条件,但不是充分条件。
将其扩展到有限的流,并且短路操作可以避免执行不必要的管道步骤,如您的示例所示。
发布于 2020-03-03 01:21:28
Arrays.asList("Fred", "Jim", "Sheila")
.stream()
.peek(System.out::println)
.allMatch(s -> s.startsWith("F"));Fred是印刷。它是如此匹配Jim被打印。它不匹配,所以allMatch终止,因为“所有的不匹配”发布于 2020-03-03 01:21:16
用于文档方法的peek说(强调我的):
返回一个由该流的元素组成的流,另外,在每个元素上执行提供的操作,因为元素是从结果流中使用的。
因此,在本例中,peek没有看到"Sheila",因为该值不是从流中使用的。一旦使用了"Jim",.allMatch(s -> s.startsWith("F"))的结果就已经知道为false,因此不需要再使用流中的任何元素。
https://stackoverflow.com/questions/60498730
复制相似问题