2016-01-22 48 views
4

以下的输入在地图列表中使用Java 8流groupingBy?

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

我怎么使用Java 8流以下输出

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

我有以下标准解决方案

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?>)) 

回答

7

要分组之前生成,你应该通过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}] 
} 
+1

毕竟,如果我想实现我最初的目标的标准方法是更可读,只是一个少一点简洁。非常感谢,我不知道'flatMap'的东西,非常有趣。 –