_Map<K,List<T>>
_を返すCollectors.groupingBy()
の場合、_List<T>
_がストリームを評価するためのものであることを意味していますか?
リストの順序についての明確な説明はありませんが、並行バージョンでは順序が明示されていません。どうにか注文されなかった場合は、コレクションであると思いますが、注文以外にどのような注文が可能かはわかりません。
各リストの最後の値が、そのグループで受信した最後の値であることが保証されていることを願っています。
groupingBy()
のドキュメントはこう言っています:
実装要件:
これにより、次のような結果が生成されます。
_groupingBy(classifier, toList());
_
toList()
のドキュメントはこう言っています:
戻り値:
すべての入力要素を遭遇順に
Collector
に収集するList
したがって、質問に答えるために、ストリームに encounter order が定義されている限り、順序付けられたリストを確実に取得できます。
編集:@Holgerが指摘するように、groupingBy()
もtoList()
の順序付け制約を維持するためにエンカウンター順序を尊重する必要があります。このことは、このメモで強く暗示されています。
実装上の注意:
...要素がダウンストリームコレクターに提示される順序を維持する必要がない場合は、
groupingByConcurrent(Function, Collector)
を使用すると、並列パフォーマンスが向上する可能性があります。
残念ながら、この保証は明確に述べられていません。
ただし、結果のCollector
には現在UNORDERED
特性がないため、実際には結果のList
が順序付けされます。
残りの問題は、それを禁止するAPI契約がないため、将来のバージョン(または代替実装)がその特性を追加して、順序付けられていないリストを生成する可能性があるということです。実際には、OpenJDKとOracleはどちらも、正当な理由がある場合でも、このような重大な変更を導入することを極端に望んでいません。
ここでは、そのような変更を行う正当な理由はほとんどありません。この振る舞いに依存するのは安全だと思います。
私は実際のテストをしました、私はArrayList<TimeBased>
この順序で:
{"1", "2019-03-22 10:20:03", "1"},
{"2", "2019-03-22 10:30:03", "2"},
{"2", "2019-03-22 11:20:03", "3"},
{"1", "2019-03-22 11:20:15", "4"},
{"3", "2019-03-22 11:35:03", "5"},
{"2", "2019-03-22 12:20:03", "6"}
およびgroupingByの最初と2番目の列ですが、結果は次のとおりです。
id birth number
1 Fri Mar 22 10:20:03 CST 2019 1
1 Fri Mar 22 11:20:15 CST 2019 4
2 Fri Mar 22 12:20:03 CST 2019 6
2 Fri Mar 22 11:20:03 CST 2019 3
2 Fri Mar 22 10:30:03 CST 2019 2
3 Fri Mar 22 11:35:03 CST 2019 5
ご覧のとおり、順序は予期されていません(日付列の順序が混乱しています)。
そして私がこれをした後(LinkedList :: newを追加):
Map<Integer, Map<Date, List<TimeBased>>> grouped =
timeBasedBeans.stream().collect(groupingBy(TimeBased::getId, groupingBy(TimeBased::getPeriod,
LinkedHashMap::new, toList())));
その後、順序は正しいです:
id birth number
1 Fri Mar 22 10:20:03 CST 2019 1
1 Fri Mar 22 11:20:15 CST 2019 4
2 Fri Mar 22 10:30:03 CST 2019 2
2 Fri Mar 22 11:20:03 CST 2019 3
2 Fri Mar 22 12:20:03 CST 2019 6
3 Fri Mar 22 11:35:03 CST 2019 5