首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >peek()和allMatch()如何在Java8StreamAPI中协同工作

peek()和allMatch()如何在Java8StreamAPI中协同工作
EN

Stack Overflow用户
提问于 2020-03-03 01:11:16
回答 4查看 922关注 0票数 9

我发现了一个关于peek方法的Java8StreamAPI的测试,如下所示

代码语言:javascript
复制
Arrays.asList("Fred", "Jim", "Sheila")
      .stream()
      .peek(System.out::println)
      .allMatch(s -> s.startsWith("F"));

输出是

代码语言:javascript
复制
Fred
Jim

我搞不懂这条小溪是怎么工作的?我的预期结果应该是

代码语言:javascript
复制
Fred
Jim
Sheila

peek()方法是一个中间操作,它处理Stream中的每个元素。有人能解释一下吗。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-03-03 01:22:56

这是一种称为短路的流优化。本质上,所发生的事情是allMatch阻止在流上执行不必要的中间操作,因为当知道最终结果时,执行这些操作没有意义。

就好像这事发生了:

代码语言:javascript
复制
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组合,有多个中间和终端短路操作。包裹的文档状态:

此外,一些操作被认为是短路操作.中间操作是短路的,如果当呈现无限输入时,它可能产生有限的流。如果在无限输入的情况下,终端操作在有限的时间内终止,则终端操作是短路的。在管道中进行短路操作是处理无限流在有限时间内正常终止的必要条件,但不是充分条件。

将其扩展到有限的流,并且短路操作可以避免执行不必要的管道步骤,如您的示例所示。

票数 9
EN

Stack Overflow用户

发布于 2020-03-03 01:21:28

代码语言:javascript
复制
Arrays.asList("Fred", "Jim", "Sheila")
      .stream()
      .peek(System.out::println)
      .allMatch(s -> s.startsWith("F"));
  • 第一次通过,Fred是印刷。它是如此匹配
  • 第二次通过,Jim被打印。它不匹配,所以allMatch终止,因为“所有的不匹配”
  • 因此,最后一项不是从流中消耗的。
票数 4
EN

Stack Overflow用户

发布于 2020-03-03 01:21:16

用于文档方法的peek说(强调我的):

返回一个由该流的元素组成的流,另外,在每个元素上执行提供的操作,因为元素是从结果流中使用的。

因此,在本例中,peek没有看到"Sheila",因为该值不是从流中使用的。一旦使用了"Jim".allMatch(s -> s.startsWith("F"))的结果就已经知道为false,因此不需要再使用流中的任何元素。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60498730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档