簡體   English   中英

通過多個鍵平整流組的結果

[英]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.asListList.of返回的List實現在其equalshashCode方法方面是明確定義的,即它們可以安全地用作任何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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM