2016-04-22 98 views
1

这个问题绝对不是重复的,因为我没有提到一般的post/precrement评估,但是专门针对在lambda表达式中使用增量,这是明显不同的。每个人都可以自由地确认代码只会在您通常期望变量值增加的位置返回零。没有答复已发布到此。后缀与lambda表达式的前缀增量

我很清楚post-和prefix前后递增的变化评估和递增时刻。不过,我不明白为什么这个只返回零:

Stream.iterate(0, e -> e++) 
      .limit(10) 
      .forEach(System.out::println); 

当检查这一点,我认为电子第一次迭代时被初始化为0,然后递增。所以第二次迭代应该产生e = 1,但显然它不会。我错过了什么?

另外,如果我扭转的增加,它的工作原理像预想的那样,从0到9,列出所有的数字:

Stream.iterate(0, e -> ++e) 
      .limit(10) 
      .forEach(System.out::println); 
+0

看起来像是错过了'e ++'返回'e'的_previous_值,当'++ e'返回更新值时。所以'e - > e ++'实际上等同于'e - > e'。 – Tunaki

+0

我不认为这是“后增量和增量前操作员如何工作?”的副本。 AdHominem的问题不在于他/他不明白“e ++”是否评估为“e”的旧值;这是他/他不明白为什么它评估的是什么,而不是“e”之后的价值,这很重要。 –

+0

@GarethMcCaughan相关问题解释说。例如这个答案http://stackoverflow.com/a/2371162/1743880 – Tunaki

回答

2

的主要问题是,你正在使用旨在用于没有副作用的表达式影响。好的IDE,编译器或审计工具应该发出警告。

形式e -> expression的lambda表达式具有参数,称为e。这不能与堆变量混淆。表达式e++++e修改参数,其不具有将比单功能评估更持久的效果。这与例如没有区别像

static int myFunction(int e) { 
    return e++; // or ++e 
} 

的方法e的修改有没有持续的影响,唯一重要的事情是什么样的价值最终会被退回,所以e -> ++e相当于e -> e+1e -> e++相当于e -> e,因此,你应该使用或者e -> e+1e -> e强调将返回的内容,而不会对参数变量执行分散的副作用。

但正如在评论中提到的,在这种特定情况下,您应该使用IntStream.range(0, 10)而不是Stream.iterate(0, e -> e+1).limit(10)IntStream.range不仅会明确记录这个意图,在目前的实施中,它对于大量的流操作具有性能优势。