彷徨う園児ニア

主に備忘録。

forEachの中ではindexが利用できない(ラムダ式使用の注意)

Javaいじってて、ロジックは簡単だったので適当にfor文をforEach処理に変えていたときに発生した問題。

forEach中ではindexが使えません。
何かで取得できたような気がしましたけど"java forEach index"とかで検索すると同じことを考えていた先人たちが使えない使えないと大合唱。

//コンパイルエラー
int i = 0;
Arrays.asList("a", "b", "c").forEach( x -> System.out.println(++i + ": " + x);


以下のようにすれば一応は書ける。

int[] i = {0};
Arrays.asList("a", "b", "c").forEach( x -> System.out.println(++i[0] + ": " + x);

ラムダはラムダ内で完結してて状態を持たせないのが良いとのことなのでこのインデックスの取得も本当はあんまりよくないのかも。

ラムダのメリットとしてよく書かれるのが、
・記述が簡潔
・テストしやすい
・入力に対して出力が一意に定まる
などですが、記述がしやすいといっても、やっぱり複雑にFuctionを渡しまくっているものだと記述は短くても容易に読めないと思います。
その場合テストもしやすくはありません。
3つ目の 入力に対して出力が一意に定まる = 外部の状態をスコープ内に持たない
これが肝で、このためにテストしやすくなる等の恩恵を受けられるのかなと。

以上から、状態をもってきていないことが明らかにすぐわかる場合や状態を持ってきたい場合は従来通りfor文で良いのかなと思います。

10月発売のEffective Java 3rd Editionにもラムダの運用とかについても説明がなされることを期待しているので、発売待ってます。