2016-01-22 3 views
4

Со следующего входаИспользование Java 8 потоков groupingBy в списке списков карт?

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

ответ

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», очень интересной. –

Смежные вопросы