Java 8 流速扫和限制交互

2022-09-03 18:25:57

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

IntStream.range(0, 10)
        .peek(System.out::print)
        .limit(3)
        .count();

输出:

012

我希望它能输出,因为偷看前置限制。0123456789

在我看来,这似乎更奇怪,因为事实是:

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

按预期输出(非 )。012345678902481012141618

P.S.:这里只是用来消费流,它可以用其他任何东西代替.count()


答案 1

关于流,需要了解的最重要的事情是,它们本身不包含元素(如集合),而是像管道一样工作,其值被懒惰地计算。这意味着在终端操作运行之前,不会评估构建流的语句(包括映射、筛选或其他任何内容)。

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

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

因此,您确实可以获得输出。012

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

  1. 打印出值
  2. 将 x 映射到 x*2,从而将值的双精度值转发到下一步

如您所见,输出先于映射,因此您得到结果 。尝试切换 和 呼叫。然后,您将获得预期的输出。0123456789peekmap


答案 2

文档中

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

map()是一个intermediate operation

同样,从文档中,这实质上意味着将返回一个流,其中包含它收到的流中的值。limit()x

如果中间操作具有无限输入,则中间操作可能因此产生有限流,则该操作是短路的。


推荐