Edited at

【Java8】拡張for文、forEach文のインデックスをimmutableにする


普通に宣言した場合

拡張for文、forEach文を普通に宣言すると以下のようになります。

final宣言していないため、再代入可能です(for文は原理的に再代入が必須なので飛ばします)。

List<Integer> intList = Arrays.asList(1, 2, 3, 4);

for(int i : intList) {
i = 0; // 書き換えられる
}

intList.forEach(it -> {
it = 0; // 書き換えられる
});

この記事では、これらの内容を再代入不能な形に書き換えます。


インデックスをimmutableにする


拡張for文の場合

finalで宣言することでimmutableにできます。

for(final int i : intList) {

i = 0; // final宣言しているため再代入不可でコンパイルエラー
}


forEach文の場合

以下のように、カッコで括って型を指定することで引数をfinalにできます。

intList.forEach((final int it) ->

it = 0; // final宣言しているため再代入不可でコンパイルエラー
);


別解

一応ですが、無名クラスとして実装する場合も引数をfinalにできます。

Consumer<Integer> finalConsumer = new Consumer<Integer>() {

@Override
public void accept(final Integer it) {
it = 0; // final宣言しているため再代入不可でコンパイルエラー
}
};


お詫び

この記事は当初公開した際「インデックスをimmutableにできるのはfor文、拡張for文、forEach文の内拡張for文だけ」というタイトル・内容でしたが、@saka1029 様のご指摘の通り、これは誤りでしたので、タイトル・内容共に全面的に書き直しを行いました。

@saka1029 様、ご指摘ありがとうございました。