提问者:小点点

带过滤器的IntStream迭代函数


我当时正在读一本名为《现代Java在行动》的书,其中一部分代码我无法理解。

      IntStream.iterate(0, n -> n + 4)
                .filter(n -> n < 100)
                .forEach(System.out::println);

作者表示,代码不会终止。原因是无法在过滤器中知道数字是否继续增加,因此它会无限地继续过滤它们!

我不明白原因。有人能解释一下为什么吗。


共2个答案

匿名用户

作者表示,代码不会终止。

是的,因为迭代的这个特定重载

static IntStream iterate(int seed,
                         IntUnaryOperator f)

返回通过将函数f迭代应用于初始元素种子而生成的无限序列有序IntStream,生成由种子、f(种子)、f(种子)等组成的流。

返回一个无限流,给定它是一个无限流,这意味着它只能通过某些操作终止。

鉴于此处使用的终端操作(forEach)不是短路,这意味着您需要“短路中间操作”来截断此特定情况下的无限流,例如限制(JDK8)、takeWhile(JDK9)等。

JDK8中唯一的短路中间操作是limited,因为它允许在有限时间内完成对无限流的计算。

原因是在过滤器中没有办法知道数字会继续增加,所以它会无限地过滤它们!

过滤器本身不是短路中间操作,因此无法终止流<代码>过滤器的工作本质上是返回一个流,该流由与给定谓词匹配的流元素组成。

结论:如果使用的是没有短路终端操作的无限流,则需要短路中间操作来截断流,否则流将保持无限。

匿名用户

int流将生成一个数字序列,该序列从0开始,步长为4。然后它们将被过滤掉。Int一直在生成,因为没有终端条件。它相当于

for(int n=0;;n=n+4){... Filter out }