2016-05-16 30 views
4

People.getAge()の昇順にソートされたリストList<People>を考えてみましょう。 Collectors.groupingBy(People::getCity)を使用してこのリストをグループ化すると、各グループ/都市の結果リストは年齢順に並べられますか?Java groupingByコレクタはリストの順序を保持しますか?

実際には、順序を保持しているようです。私は保証を求めています。

方法のJavadocは言う:

要素が得られたマップコレクタに現れる順序の保存が必要でない場合、groupingByConcurrent(機能)を使用すると、より良好な並列性能を提供することができる

これは、リスト上のアイテムの順序を参照するかわかりません。

+1

あなたのJavadocの見積もりには、明らかに明記されています。なぜあなたは疑問を持っていますか? –

+0

@FrankPuffer:Map Collectorでは、Map要素を構築するために使用されたtoListコレクタを参照していますか? – Prateek

+0

@FrankPuffer:「groupingBy」は順序を保持していますが、残念ながら[Collectors.groupingBy'のJavaDoc](http://docs.oracle.com/javase/8/docs/api /java/util/stream/Collectors.html#groupingBy-java.util.function.Function-)はそれについて何も言わない。 OpenJDKの実装を見たり、経験的なテストをすることができますが、私たちに言うことは、実装が現在行っていることであり、契約とは異なります。だからうまくいけば、JDK APIドキュメントの*どこかに明確になっているはずです。 –

答えて

1

契約を理解するための鍵は、「要素が表示される順番は」となっています。それらが順番に到着したかどうかについては、鍵抽出器Functionに渡されているかどうか、および下流のコレクタに順番に渡されるかどうかが示されます。それは結果の蓄積に命令が保存されるかどうかについて何も言わない。実際にはgroupingByの現在の実装では、キーの順序を保持しないHashMapが使用されています。

リストの項目の順序を参照するかどうかを確認します。ストリームが作成されたリストを参照している場合、リスト上に作成されたストリームは順序付けられますが、一部のストリーム操作では順序が変更されるか順不同になるため、パイプライン後の順序が参照されますストリームが順序付けられている場合に操作が実行されます。ストリーム操作によってストリームが順序付けられない場合、要素がコレクタに表示される順序はもう問題になりません。

リスト内のアイテムの順序を参照している場合、グループ化されたアイテムは収集されます。「表示される順序」は、その要素が処理される順序であるためです。ダウンストリームコレクタにグループ化する場合も同様です。 Streamがまだ注文されていて、注文を保存しているダウンストリームコレクタにグループ化すると、この注文は保存されますが、Concurrentバージョンは維持されません。

+0

引用されたJavadocは、 "**結果の**マップに表示される要素の順序を保存すると..."です。正確に言うと、** result **の注文は保存されているとしか言えません。それは、次のように解釈することができます:同じ入力を与えた場合、何回処理しても、結果の順序は同じです。そのため、着信**ストリームでの順序付けさえ保持されない場合、結果が一貫している限り、Javadocの説明どおりに処理されます。 (私はまた、Javadocの本来の意図は、入力に対応して順序が保持されていると考えていますが、あいまいで書かれています) –

関連する問題