回答編集履歴
2
swordoneさんのdata.forEach()は副作用ではないという意見に同意
answer
CHANGED
@@ -27,9 +27,8 @@
|
|
27
27
|
|
28
28
|
> foreachではdataが書き換わってしまうという事ぐらいでしょうか?(stream api は新しいcollectionに対しての操作という認識)
|
29
29
|
|
30
|
-
|
30
|
+
data.stream().forEach()は元のデータを書き換える副作用があります(新しい出力を作らず終端処理で自己更新する)。(*swordoneさんのdata.forEach()は副作用ではないという意見に同意。以後、Stream処理が入力を汚すという意味で「副作用」を使います)
|
31
31
|
|
32
|
-
|
33
32
|
**map/peek**
|
34
33
|
|
35
34
|
さらに副作用のある例を2つ示します。map()は戻り値を返す必要があります。peek()は戻り値なしです。
|
1
訂正とStreamの利用を追記
answer
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
> ① stream api と foreachの違いはなんでしょうか?
|
20
20
|
|
21
|
-
forEach()は
|
21
|
+
forEach()はCollectionとStreamの両方にあります。どちらも引数にConsumerを取ります。違いは[The Difference Between Collection.stream().forEach() and Collection.forEach()](https://www.baeldung.com/java-collection-stream-foreach)に書かれているとおり、Collectionが内部的にIteratorを使用するのに対してStreamはListを順にトラバースします。Iteratorを書き換えると処理順が変わります。この例でその必要はなさそうです。
|
22
22
|
|
23
23
|
```Java
|
24
24
|
data.forEach(e->e.add(999));
|
@@ -27,25 +27,26 @@
|
|
27
27
|
|
28
28
|
> foreachではdataが書き換わってしまうという事ぐらいでしょうか?(stream api は新しいcollectionに対しての操作という認識)
|
29
29
|
|
30
|
-
どちらも元のデータを書き換える副作用があります。
|
30
|
+
どちらも元のデータを書き換える副作用があります。Collectionの更新メソッドを呼ぶから。
|
31
31
|
|
32
32
|
|
33
33
|
**map/peek**
|
34
34
|
|
35
35
|
さらに副作用のある例を2つ示します。map()は戻り値を返す必要があります。peek()は戻り値なしです。
|
36
36
|
|
37
|
-
> ③ stream apiを使うとしたら、どのように元のListにキャストするのでしょうか?
|
38
|
-
|
39
|
-
すでに(List<Integer>)のStreamになっているのでキャストできません。`.collect(Collectors.toList())`で、新しく外側のListを作ってもとの中身を格納します。
|
40
|
-
|
41
37
|
```Java
|
42
38
|
data.stream().map(e -> {e.add(999);return e;}).collect(Collectors.toList());
|
43
39
|
data.stream().peek(e -> e.add(999)).collect(Collectors.toList());
|
44
40
|
```
|
45
41
|
|
42
|
+
> ③ stream apiを使うとしたら、どのように元のListにキャストするのでしょうか?
|
43
|
+
|
44
|
+
すでに(List<Integer>)のStreamになっているのでキャストできません。`.collect(Collectors.toList())`で、新しく外側のListを作ってもとの中身を格納します。
|
45
|
+
|
46
|
+
|
46
47
|
**すべてを作り直す**
|
47
48
|
|
48
|
-
中身をすべてコピーして新しく作るやり方です。入力はそのまま残り、副作用はありません。
|
49
|
+
中身をすべてコピーして新しく作るやり方です。入力はそのまま残り、副作用はありません。この方法だと`data`を作る時に`ArrayList::new`が不要になります。
|
49
50
|
|
50
51
|
```Java
|
51
52
|
data.stream()
|
@@ -57,4 +58,8 @@
|
|
57
58
|
|
58
59
|
- Stream/Collectionは、どちらも副作用がある
|
59
60
|
- Streamは、filter/mapなどのメソッドチェーンが使えるので、データを加工するならStreamを使う
|
60
|
-
- Collectionは、Iteratorを書き換えて、処理の順番を変えることができる
|
61
|
+
- Collectionは、Iteratorを書き換えて、処理の順番を変えることができる
|
62
|
+
|
63
|
+
**Streamの利用**
|
64
|
+
|
65
|
+
Streamhは並行処理で利用することがあり、副作用が起きないようにimmutableなコレクションを扱うほうがよい。また、immutableにしておけば、誤ってコレクションを更新しても例外が発生する。
|