Java 8流查看和限制交互

tsd*_*sds 14 java java-8 java-stream

为什么这个代码在java 8中:

IntStream.range(0, 10)
        .peek(System.out::print)
        .limit(3)
        .count();
Run Code Online (Sandbox Code Playgroud)

输出:

012
Run Code Online (Sandbox Code Playgroud)

我希望它输出0123456789,因为窥视优先于限制.

在我看来更奇怪,因为这个事实:

IntStream.range(0, 10)
        .peek(System.out::print)
        .map(x -> x * 2)
        .count();
Run Code Online (Sandbox Code Playgroud)

0123456789按预期输出(不是02481012141618).

PS:.count()这里仅用于消耗流,它可以被其他任何东西替换

See*_*ose 16

关于流的最重要的事情是它们本身不包含元素(如集合),但它们的工作方式就像管道的值被懒惰地评估.这意味着在终端操作运行之前,不会评估构建流的语句(包括映射,过滤或其他).

在第一个示例中,流尝试从0到9进行计数,每次执行以下操作:

  1. 打印出来的价值
  2. 检查是否传递了3个值(如果是,则终止)

所以你真的得到了输出012.

在第二个示例中,流再次从0到9计数,每次执行以下操作:

  1. 打印出来的价值
  2. maping x to x*2,从而将值的两倍转发到下一步

正如您所看到的那样,输出位于映射之前,因此您可以获得结果0123456789.尝试切换peekmap拨打电话.然后你会得到你期望的输出.


Sou*_*tra 7

来自文档:

limit() 是一个 short-circuiting stateful intermediate operation.

map() 是一个 intermediate operation

再次从文档中,本质上意味着limit()将返回一个流,其中x包含来自其收到的流的值.

如果在呈现无限输入时,它可能产生有限流,则中间操作是短路的.


Hol*_*ger 5

Streams 被定义为进行惰性处理。因此,为了完成您的count()操作,\xe2\x80\x99 不需要查看其他项目。否则,它就会被破坏,因为它limit(\xe2\x80\xa6)被定义为在有限时间内处理无限流的正确方法(通过不处理多个limit项目)。

\n\n

原则上,完全不需要查看值就可以完成您的请求int,因为操作链limit(3).count()不需要对先前操作进行任何处理(除了验证流是否至少有3项目) 。

\n