うまくいかない原因はlambda式の使い方ではなくてStream APIについての勘違いのようです。
Stream APIではパイプラインの各段は前のパイプラインから受け取った値を計算して次のパイプラインへ渡す(複数のパイプラインの間で流れ作業のように要素を加工していく)のが基本です。パイプラインの最終段は終端操作と呼ばれ、以下のいずれかを行います。
(A) 前段までのパイプラインで計算された結果を最終的な値へ変換(蓄積, 簡約, etc.)
(B) 前段までのパイプラインで計算された各要素の値を使って副作用を起こす
ご質問のコードにあるforEachは(B)のためのメソッドですが、各要素を2倍してはいるものの、それを元のリストへ書き戻すことができていません。
各要素を2倍したリストを作るのは(A),(B)いずれの考え方でもできます。
(A)の考え方
java
1list = list.stream() // (1)
2 .map(i -> i * 2) // (2)
3 .collect(Collectors.toList()); // (3)
(1) のリストの各要素をパイプラインへ渡す
(2) (1)から受け取った各要素を2倍して次のパイプラインへ渡す
(3) (2)から受け取った各要素をListへ蓄積(Collect)し、全要素を集め終わったら結果を返す
(B)の考え方
java
1IntStream.range(0, list.size()).forEach(i ->
2 list.set(i, list.get(i) * 2) // 要素を取り出し2倍し元の値を書き換える(副作用)
3);
forEachの方は副作用(元のリストへ計算結果を書き戻す)ためにインデックスが必要なため、パイプライン上へ要素の値ではなくインデックスを流しています。(個人的には)for文を使うのと大差ないように思えます。
追記:swordoneさんコメントのように、Stream APIに副作用を用いると注意が必要です。一般には(A)を使い、パイプラインの各段には「副作用がない関数操作のみに限定する」のがお勧めと思います。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/12 12:27 編集
2017/06/12 12:28 編集
2017/06/12 12:27
2017/06/12 12:31
2017/06/12 20:23