我碰巧知道,在下面的表达式中,使用i++将导致无限流,i将始终为0。我感到困惑是因为我认为没有使用i++返回值,即使这样,它也不应该在之后中断i的递增。
IntStream.iterate(0, i-> i<10, i-> ++i).forEach(....)发布于 2017-08-02 09:28:37
通过检查Java9 IntStream的接口:http://download.java.net/java/jdk9/docs/api/java/util/stream/IntStream.html#iterate-int-java.util.function.IntPredicate-java.util.function.IntUnaryOperator-
最后一个函数(在本例中为i -> ++i)用于确定下一个值。
如果您放入i->i++,假设它是一个后缀增量运算符,则i++在增量之前的计算结果为i。这意味着它总是返回相同的值(在本例中为seed 0 )。因此,它的工作原理就像你把i -> i。请注意,Java中的参数是通过值传递的。因此,您在lambda中的增量不会影响调用者。
因此,hasNext谓词(第二个参数,在本例中为i->i<10 )的计算结果总是为true,因此会给出一个全为0的无限流。
发布于 2017-08-02 09:24:13
您可以使用limit并执行您建议的操作:
IntStream.iterate(0, i -> i++).limit(10).forEach(....)这也可能会有所帮助:
发布于 2017-08-03 22:07:31
记住,lambda表达式是一种将函数接口(只有一个抽象方法的接口)的实现表示为匿名函数的方法。
在您的iterate()方法中,第三个参数是一个IntUnaryOperator。它只有一个抽象方法applyAsInt(),它接受一个整数作为参数并返回一个整数。如果您将Lambda表达式重写为等效的匿名内部类(您可以在这里非常合法地使用它),您将得到:
IntStream.iterate(0, i -> i < 10, new IntUnaryOperator() {
@Override
public int applyAsInt(int i) {
return i++;
}
})
.forEach(System.out::println);在这种情况下,很明显,您返回的是i在递增之前的值(后缀运算符)。I的初始值是零,所以你会得到一个无限的0流。如果将applyAsInt()方法更改为使用前缀运算符++i,则i的值将会递增,然后才会返回所需的结果1,2...9
https://stackoverflow.com/questions/45449945
复制相似问题