Java 8 中針對複雜物件結構的巢狀分組
在Java 8 中,Collectors.groupingBy 方法提供了一個強大的方法來根據關於特定屬性。這使您可以有效地聚合和匯總資料。但是,如果要執行多個層級的分組,情況又如何呢?
考慮以下類別結構:
<code class="java">class Pojo { List<Item> items; } class Item { T key1; List<SubItem> subItems; } class SubItem { V key2; Object otherAttribute1; }</code>
目標是根據 key1 將項目分組,然後對每個項目進行分組item group,並根據key2進一步分組子item。所需的輸出是以下形式的映射:
<code class="java">Map<T, Map<V, List<SubItem>>></code>
使用標準 Collectors.groupingBy 不足以滿足此場景。挑戰在於透過多個按鍵將單一項目分組。
解:扁平化結構
解決此問題的關鍵是暫時扁平化結構。透過這樣做,您可以在執行必要的分組之前建立 Item 和 SubItem 的組合流。
一種方法是使用Stream.flatMap 方法建立Map.Entry 物件流,其中每個條目代表一對Item 和SubItem:
<code class="java">Map<T, Map<V, List<SubItem>>> result = pojo.getItems().stream() .flatMap(item -> item.subItems.stream() .map(sub -> new AbstractMap.SimpleImmutableEntry<> (item.getKey1(), sub))) .collect(Collectors.groupingBy(AbstractMap.SimpleImmutableEntry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.groupingBy(SubItem::getKey2))));</code>
Collectors.flatMapping 的替代解決方案(Java 9 )
在Java 9 及更高版本中,更優雅的方法是使用Collectors.flatMapping 收集器可用:
<code class="java">Map<T, Map<V, List<SubItem>>> result = pojo.getItems().stream() .collect(Collectors.groupingBy(Item::getKey1, Collectors.flatMapping(item -> item.getSubItems().stream(), Collectors.groupingBy(SubItem::getKey2))));</code>
結論
透過利用Streams、Collectors 和臨時物件扁平化,甚至可以實現嵌套分組Java 8 及更高版本中的複雜物件結構。
以上是如何在 Java 8 中基於多個屬性執行巢狀分組的詳細內容。更多資訊請關注PHP中文網其他相關文章!