1. ホーム
  2. java

[解決済み] Java 8 Streams - コレクト vs リデュース

2022-04-26 15:49:56

質問

どのような場合に collect()reduce() ? どなたか、どちらかにした方が絶対に良いという具体的な良い例をお持ちの方はいらっしゃいますか?

Javadocによると、collect()はmutable reductionであるとのことです。 .

ミュータブルリダクションということは、(内部で)同期が必要なのだと思いますが、これは逆にパフォーマンスを低下させる可能性があります。 おそらく reduce() は、reduceの各ステップの後にreturnのための新しいデータ構造を作成しなければならない代償として、より容易に並列化することができます。

しかし、上記の記述は推測であり、専門家の意見を聞きたいところです。

解決方法は?

reduce は"です。 折りたたみ 演算子の第1引数は直前のアプリケーションの戻り値で、第2引数は現在のストリーム要素です。

collect は集約操作で、quot;collection"が作成され、各要素はそのコレクションにquot;add"される。ストリームの異なる部分にあるコレクションは、一緒に追加される。

リンク先の文書 には、2つの異なるアプローチをとる理由が書かれています。

もし、文字列のストリームを受け取り、それらを連結して1つの 長い文字列を1つ作るには、通常のリダクションで実現できます。

 String concatenated = strings.reduce("", String::concat)  

期待通りの結果が得られ、並列に動作することも可能です。 しかし、パフォーマンスについては満足できないかもしれません。このような の実装では、大量の文字列コピーを行うことになり、その実行は は文字数でO(n^2)になってしまう。より性能の良い この場合、結果はStringBuilderに蓄積されます。 これは、文字列を蓄積するための変更可能なコンテナである。このコンテナは文字列を蓄積するためのミュータブルコンテナです。 ミュータブルリダクションを並列化するための手法は、通常の を削減することができます。

つまり、要は並列化はどちらも同じなのですが、その中で reduce の場合は、ストリーム要素自体に関数を適用しています。このとき collect の場合、関数はミュータブルコンテナに適用されます。