2016-04-22 170 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不僅會明確記錄這個意圖,在目前的實施中,它對於大量的流操作具有性能優勢。