Java 带过滤器的IntStream迭代函数

Java 带过滤器的IntStream迭代函数,java,filter,java-stream,intstream,Java,Filter,Java Stream,Intstream,我在读这本书,书名是《和一部分我无法理解的代码》 IntStream.iterate(0, n -> n + 4) .filter(n -> n < 100) .forEach(System.out::println); IntStream.iterate(0,n->n+4) .过滤器(n->nn.add(biginger.TWO)).filter(n->n.compareTo(biginger.va

我在读这本书,书名是《和一部分我无法理解的代码》

      IntStream.iterate(0, n -> n + 4)
                .filter(n -> n < 100)
                .forEach(System.out::println);
IntStream.iterate(0,n->n+4)
.过滤器(n->n<100)
.forEach(System.out::println);
作者说代码不会终止。 原因是在过滤器中没有办法知道数字继续增加,所以它会无限地过滤它们


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

int流将生成一个从0开始并具有步骤4的数字序列。然后它们将被过滤掉。由于没有终端条件,Int将继续生成。相当于

for(int n=0;;n=n+4){... Filter out }
作者说代码不会终止

是的,因为这个特定的

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

返回一个无限流,如果它是一个无限流,则意味着它只能通过某些操作终止

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

唯一的限制是
限制
,因为它允许在有限时间内完成无限流上的计算

原因是无法在筛选器中知道 数字不断增加,所以它不断地过滤它们 无限远

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


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

为什么此post关闭?问题很清楚。。。OP想更清楚地解释一下@Rakesh“为什么这个流没有终止”——你能详细说明一下,你不理解指定原因中的哪一部分吗?这实际上是一个坏例子,因为
int
值将溢出(在最新的环境中很快就会溢出)并永远循环通过
int
数据范围。应该清楚的是,跳过
[100‑Integer.MAX_VALUE]
范围不会改变迭代的无限性。更好的例子是
Stream.iterate(biginger.ZERO,n->n.add(biginger.TWO)).filter(n->n.compareTo(biginger.valueOf(100))<0.forEach(System.out::println)。但是甚至
IntStream.generate(()->42).filter(n->false).forEach(System.out::println)将永远循环,尽管没有任何可感知的结果。@Holger:我的意图是问为什么它不停止,我相信这个例子已经足够好了。但是为什么它应该停止呢?源流是无限的,
filter
只告诉我们跳过不匹配的元素。假设它可以停止的唯一原因是假设在超过
n<100
阈值后不会出现任何元素。这是完全错误的,因为持续增加
int
值会溢出,并且在超过阈值后会出现元素。说到流API,我的
biginger
示例将更好地说明这个问题,因为它表明,即使在超过阈值后确实没有元素,流也将继续测试。很好的解释。我明白了为什么它没有终止。
static IntStream iterate(int seed,
                         IntUnaryOperator f)