【问题标题】:Using Java 8 streams groupingBy on a list of list of maps?在地图列表上使用 Java 8 流 groupingBy?
【发布时间】:2016-01-22 12:24:48
【问题描述】:

来自以下输入

[
   [{group=a, value=cat}, {group=b, value=dog}],
   [{group=a, value=cow}, {group=b, value=bat}]
]

我如何得到以下输出

{
   a=[{value=cat}, {value=cow}],
   b=[{value=dog}, {value=bat}]
}

使用 Java 8 流?

我有以下标准解决方案

Map<String, String > map1 = new LinkedHashMap<>();
map1.put("group", "a");
map1.put("value", "cat");
Map<String, String > map2 = new LinkedHashMap<>();
map2.put("group", "b");
map2.put("value", "dog");
Map<String, String > map3 = new LinkedHashMap<>();
map3.put("group", "a");
map3.put("value", "cow");
Map<String, String > map4 = new LinkedHashMap<>();
map4.put("group", "b");
map4.put("value", "bat");

List<Map<String, String>> list1 = Arrays.asList(map1, map2);
List<Map<String, String>> list2 = Arrays.asList(map3, map4);

List<List<Map<String, String>>> input = Arrays.asList(list1, list2);

Map<String, List<Map<String, String>>> output = new LinkedHashMap<>();
for (List<Map<String, String>> list : input) {
   for (Map<String, String> map : list) {
       String group = map.get("group");
       if (!output.containsKey(group)) {
           output.put(group, new ArrayList<>());
       }
       List<Map<String, String>> values = output.get(group);
       values.add(map);
   }
}

看到有Collectors.groupingBy的方法,但是不知道怎么用。

Map<String, List<Map<String, String>>> output = input.stream()
  .<am I missing out some steps here?>
  .collect(Collectors.groupingBy(<what goes here?>))

【问题讨论】:

    标签: java collections java-8 java-stream


    【解决方案1】:

    要生成相同的输出,您应该在分组之前通过flatMap 将列表列表展平为单个列表:

    output = input.stream().flatMap(List::stream)
                  .collect(Collectors.groupingBy(map -> map.get("group")));
    

    此代码生成与您发布的命令式代码相同的输出:

    {
     a=[{group=a, value=cat}, {group=a, value=cow}], 
     b=[{group=b, value=dog}, {group=b, value=bat}]
    }
    

    但请注意,它与您想要的输出不同。要获得所需的输出,您可能需要指定下游收集器:

    output = input.stream()
                  .flatMap(List::stream)
                  .collect(Collectors.groupingBy(map -> map.get("group"),
                     Collectors.mapping(
                         map -> Collections.singletonMap("value", map.get("value")), 
                          Collectors.toList())));
    

    现在结果是

    {
      a=[{value=cat}, {value=cow}], 
      b=[{value=dog}, {value=bat}]
    }
    

    【讨论】:

    • 毕竟,如果我想实现我最初的目标,那么标准方法的可读性要高得多,而且不那么简洁。不过还是谢谢,我不知道flatMap这个东西,很有趣。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    相关资源
    最近更新 更多