[英]Flatten result of stream group by multiple keys
我想在java中使用流來根據多個字段對長對象列表進行分組。 這將導致列表地圖的地圖的地圖的地圖的地圖。
我怎樣才能從該復雜流中提取列表?
以下是一些示例代碼示例(字符串列表,查找具有相同長度和首字母的組)。 我對密鑰不感興趣,只是在生成的分組實體中。
List<String> strings = ImmutableList.of("A", "AA", "AAA", "B", "BB", "BBB", "C", "CC", "CCC", "ABA", "BAB", "CAC");
Map<Character, Map<Integer, List<String>>> collect = strings.stream().collect(
groupingBy(s -> s.charAt(0),
groupingBy(String::length)
)
);
這將產生以下結果
My Map =
{
A =
{
1 = [A]
2 = [AA]
3 = [AAA, ABA]
}
B =
{
1 = [B]
2 = [BB]
3 = [BBB, BAB]
}
C =
{
1 = [C]
2 = [CC]
3 = [CCC, CAC]
}
}
我感興趣的實際上只是上面結果中的列表,我想在理想情況下將其作為groupby操作的一部分。 我知道可以通過循環生成的地圖結構來完成。 但有沒有辦法使用流來實現它?
[
[A],
[AA],
[AAA, ABA],
[B],
[BB],
[BBB, BAB],
[C],
[CC],
[CCC, CAC]
]
不使用級聯Collectors.groupingBy
創建嵌套組,而應使用組合鍵進行分組:
Map<List<Object>, List<String>> map = strings.stream()
.collect(Collectors.groupingBy(s -> Arrays.asList(s.charAt(0), s.length())));
然后,只需抓取地圖值:
List<List<String>> result = new ArrayList<>(map.values());
如果您使用的是Java 9+,則可能需要從Arrays.asList
更改為List.of
以創建組合鍵。
這種方法適用於您的情況,因為您聲明您對保留密鑰不感興趣,並且因為Arrays.asList
和List.of
返回的List
實現在其equals
和hashCode
方法方面是明確定義的,即它們可以安全地用作任何Map
鍵。
如果你想獲得List<List<String>>
,你可以使用:
List<List<String>> list = collect.entrySet().stream()
.flatMap(e -> e.getValue().entrySet().stream())
.map(Map.Entry::getValue)
.collect(Collectors.toList());
此外,如果要獲取單個字符串列表,還可以添加一個flatMap
操作:
...
.flatMap(e -> e.getValue().entrySet().stream())
.flatMap(e -> e.getValue().stream())
...
正如@John Bollinger所提到的,使用值流,但不是條目將更簡單。
我想在java中使用流來根據多個字段對長對象列表進行分組。
這比你的(無效的)示例代碼讓我覺得你期望的要復雜。 不過,您可以通過其適當命名的flatMap()
方法展flatMap()
。 對於您描述的流,您可能需要多次展平或定義自定義映射方法或復雜lambda以一直展平到您所追求的內容。
對於問題中顯示的表單的地圖,您可能會執行以下操作:
List<List<String>> result = myMap.values().stream()
.flatMap(m -> m.values().stream()) // as many of these as needed
.collect(Collectors.toList());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.