为什么在 lambda 中使用 ++i 而不是 i++
why using ++i but not i++ in lambda
我碰巧知道,在下面的表达式中,使用 i++
会导致无限流,i
将始终为 0。我感到困惑是因为我认为 i++
不使用返回值,即便如此,也不应中断 i
之后的递增。
IntStream.iterate(0, i-> i<10, i-> ++i).forEach(....)
您可以使用限制并按照您的建议进行操作:
IntStream.iterate(0, i -> i++).limit(10).forEach(....)
这也可以帮助:
Java Incremental operator query (++i and i++)
通过检查 Java 的 API 9 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
)始终计算为真,因此为您提供无限的全零流。
请记住,lambda 表达式是一种将功能接口(只有一个抽象方法的接口)的实现表示为匿名函数的方式。
在您的 iterate() 方法中,第三个参数是一个 IntUnaryOperator。它有一个抽象方法 applyAsInt(),它接受一个 int 作为参数和 returns 一个 int。如果您将 Lambda 表达式重写为等效的匿名内部 class(您可以在此处合法使用),您将得到:
IntStream.iterate(0, i -> i < 10, new IntUnaryOperator() {
@Override
public int applyAsInt(int i) {
return i++;
}
})
.forEach(System.out::println);
在这种情况下,很明显您要返回 i 递增之前的值(后缀运算符)。 i 的初始值为零,因此您将获得无限的零流。如果您将 applyAsInt() 方法更改为使用前缀运算符 ++i,则 i 的值将在返回之前递增,从而为您提供所需的结果 1、2 ... 9
我碰巧知道,在下面的表达式中,使用 i++
会导致无限流,i
将始终为 0。我感到困惑是因为我认为 i++
不使用返回值,即便如此,也不应中断 i
之后的递增。
IntStream.iterate(0, i-> i<10, i-> ++i).forEach(....)
您可以使用限制并按照您的建议进行操作:
IntStream.iterate(0, i -> i++).limit(10).forEach(....)
这也可以帮助:
Java Incremental operator query (++i and i++)
通过检查 Java 的 API 9 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
)始终计算为真,因此为您提供无限的全零流。
请记住,lambda 表达式是一种将功能接口(只有一个抽象方法的接口)的实现表示为匿名函数的方式。
在您的 iterate() 方法中,第三个参数是一个 IntUnaryOperator。它有一个抽象方法 applyAsInt(),它接受一个 int 作为参数和 returns 一个 int。如果您将 Lambda 表达式重写为等效的匿名内部 class(您可以在此处合法使用),您将得到:
IntStream.iterate(0, i -> i < 10, new IntUnaryOperator() {
@Override
public int applyAsInt(int i) {
return i++;
}
})
.forEach(System.out::println);
在这种情况下,很明显您要返回 i 递增之前的值(后缀运算符)。 i 的初始值为零,因此您将获得无限的零流。如果您将 applyAsInt() 方法更改为使用前缀运算符 ++i,则 i 的值将在返回之前递增,从而为您提供所需的结果 1、2 ... 9