1. ホーム
  2. java

[解決済み] java8のストリームで処理の順番を確保する方法は?

2022-04-20 19:54:28

質問

の中でリストを処理したい。 XML javaオブジェクトです。私は、すべての要素を受け取った順に処理することを保証しなければなりません。

そのため sequential をそれぞれの stream 私が使っている? list.stream().sequential().filter().forEach()

それとも、並列処理をしない限り、ストリームを使うだけで十分なのでしょうか? list.stream().filter().forEach()

どのように解決するのですか?

質問が間違っています。あなたが質問しているのは sequential vs. parallel を処理したいのに対して、アイテム 順番に について尋ねる必要があります。 順序 . もし、あなたが オーダー ストリームで、順序の維持を保証する操作を行った場合、ストリームが並列処理されるか順次処理されるかは関係なく、実装は順序を維持します。

順序付けされた特性は、パラレルとシーケンシャルとは区別されます。例えば、もしあなたが stream() の上に HashSet を呼び出している間、ストリームは順番通りにならない。 stream() の上で List は順序付きストリームを返す。を呼び出すことができることに注意してください。 unordered() を使用することで、順序付けの契約を解除し、パフォーマンスを向上させることができる可能性があります。一旦ストリームに順序がなくなると、順序を再確立する方法はありません。(順序のないストリームを順序のあるストリームにする唯一の方法は sorted しかし、その結果得られる順序は必ずしも元の順序とは限らない)。

も参照してください。 「順序付け」セクション java.util.stream パッケージ・ドキュメント .

ストリーム操作全体を通して順序を維持するためには、ストリームのソース、すべての中間操作、終端操作が順序を維持しているかどうか(あるいはソースがそもそも順序を持っているかどうか)についてのドキュメントを研究する必要があります。

これは非常に微妙なことで、例えば Stream.iterate(T,UnaryOperator) は順序付きストリームを作成しますが Stream.generate(Supplier) を作成します。 順序不同 ストリームを使用します。なお、質問では以下のようによくある間違いをしています。 forEach はしません。 は順序を維持します。そのため forEachOrdered ストリームの要素を保証された順序で処理したい場合。

そのため、もし list は、確かに java.util.List は、その stream() メソッドは オーダーメイド ストリームと filter は、順序を変更しません。ですから、もしあなたが list.stream().filter() .forEachOrdered() の場合、すべての要素が順番に処理されます。 list.parallelStream().filter().forEachOrdered() は並列に処理されるかもしれませんが (例えばフィルタによって)、 それでも最終アクションは順番に呼ばれます (これは明らかに並列実行の利点を減らすことになります)。

例えば、以下のような操作を行った場合

List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());

の場合、処理全体は並列実行の恩恵を受けるかもしれませんが、並列ストリームと逐次ストリームのどちらを使っても、結果のリストは常に正しい順序になります。