Суммирование значений карты по каждому ключу

#java

#java

Вопрос:

У меня есть следующие карты:

 {21=0, 22=2, 11=0, 12=0}
{21=3, 22=0, 11=6, 12=3}
{21=6, 22=0, 11=7, 12=0}
{21=5, 22=7, 11=9, 12=1}
  

Следующий код возвращает эти карты:

 for (Chrom t: obj.getChroms) {
    Map<Integer, Integer> result = t.getExecutionCount();
}
  

Метод getExecutionCount() возвращает единственную карту. Для примера, который я привел выше, у меня есть четыре хрома, где каждый хром возвращает одну карту.

Я хотел бы суммировать значения каждого ключа отдельно, чтобы конечный результат был:

 21 = 14
22 = 9
11 = 22
12 = 4
  

Возможно ли использовать stream для этого? Если нет, то как я могу это сделать?

Комментарии:

1. Это можно сделать с помощью потоков

2. Какую структуру имеют ваши карты? Это Map<Integer, Integer> ?

3. @deHaar Да, это Map<Integer, Integer>

4. Map<Integer, Integer> карта не может храниться 21=0 и 21=3 одновременно. Карта представляет пары ключ-значение, где ключ должен быть уникальным. Может быть, вы имели в виду Map<Integer,List<Integer>> ?

5. Это не одна карта, а несколько карт. Итак, сначала вам нужно создать из них единую коллекцию

Ответ №1:

Попробуйте это:

     List<Map<Integer, Integer>> maps;

    Map<Integer, Integer> result = maps.stream()
            .map(Map::entrySet)
            .flatMap(Collection::stream)
            .collect(Collectors.groupingBy(
                    Map.Entry::getKey,
                    Collectors.summingInt(Map.Entry::getValue)));
  

Ответ №2:

Вы можете создать поток карт и использовать flatMap ,

 Stream.of(map1, map2, map3)
      .flatMap(m -> m.entrySet()
                     .stream())
      .collect(Collectors.groupingBy(
                   Map.Entry::getKey,
                   Collectors.summingInt(Map.Entry::getValue)
               )
      );
  

Ответ №3:

Это возможно с помощью Stream . Это должно сработать (к сожалению, я не могу скомпилировать прямо сейчас)

 Map<Integer, Integer> result = Stream.of(map1, map2, map3, map4)
                                     .map(Map::entrySet)
                                     .flatMap(Set::stream)
                                     .collect(Collectors.toMap(
                                                  Map.Entry::getKey,
                                                  Map.Entry::getValue,
                                                  Integer::sum)
                                     );
  

Небольшое объяснение

  • Поток по всем вашим Map
  • Сделайте уникальным Stream все записи, содержащиеся внутри ваших Map
  • Сгруппируйте каждый по ключу
  • Для коллизий используйте Integer::sum , который уменьшит оба значения для одного и того же ключа