这个问题肯定不是重复的,因为我没有提到一般的post / precrement评估,而是专门讨论lambda表达式中增量的使用,这种情况可以证明是不同的。每个人都可以自由地确认代码只会在您通常期望变量值增加的位置返回零。没有回答。
我很清楚后期和前缀增量的不同评估和增量时刻。尽管如此,我还是不明白为什么它只返回零:
Stream.iterate(0, e -> e++)
.limit(10)
.forEach(System.out::println);
检查时,我看到e在第一次迭代期间被初始化为0,然后递增。因此第二次迭代应该产生e = 1,但显然它不会。我错过了什么?
此外,如果我反转增量,它按预期工作,列出0到9之间的所有数字:
Stream.iterate(0, e -> ++e)
.limit(10)
.forEach(System.out::println);
答案 0 :(得分:3)
主要问题是你使用的副作用表达式没有效果。好的IDE,编译器或审计工具应该发出警告。
e -> expression
形式的lambda表达式有一个名为e
的参数。这不能与堆变量混淆。表达式e++
和++e
将修改参数,该参数的效果不会超过单一函数评估。它没有区别,例如,像
static int myFunction(int e) {
return e++; // or ++e
}
e
的修改没有持久效果,唯一重要的是最终会返回什么值,因此e -> ++e
相当于e -> e+1
而e -> e++
是相当于e -> e
因此,您应该使用e -> e+1
或e -> e
来强调将返回的内容,而不会对参数变量造成分散注意力的副作用。
但正如评论中所述,在这种特定情况下,您应该使用IntStream.range(0, 10)
而不是Stream.iterate(0, e -> e+1).limit(10)
。 IntStream.range
不仅会清楚地记录意图,在当前的实现中,它对许多流操作都有性能优势。