Эффективно объединить два массива карт - PullRequest
2 голосов
/ 28 апреля 2019

Перед лицом сложной задачи найти эффективный способ объединения двух массивов карт.

Карта выглядит следующим образом:

{Username=User1, Role=Admin}

Таким образом, один список выглядит следующим образом:

List1 =  [{Username=User1, Role=Admin},{Username=User2, Role=Auditor}]

и т. Д.

Существует еще один список:

List 2 = [{Username=User1, Role=Integrator},{Username=User2, Role=Manager}]

Примечание: Пользователи имеют разные ролив разных списках.

В итоге я хочу получить следующее:

MergedList = [{Username=User1, Role=[Admin,Integrator]},{Username=User2, Role=[Auditor,Manager}]

Другое примечание: Фактический список содержит 50 000 карт икаждая карта имеет 20 входов!Просто постарался сделать это просто.

Ниже приведены материалы, которые я пробовал.Но не удалось.

Попробовал putAll.Пробовал merge.

Пробовал то, что нашел в другом посте

map2.forEach((k, v) -> map3.merge(k, v, String::concat));

Ответы [ 2 ]

1 голос
/ 28 апреля 2019

Вы можете использовать Java Streams для достижения этой цели:

Map<String, List<String>> result = Stream.concat(users1.stream(), users2.stream())
        .collect(Collectors.groupingBy(m -> m.get("Username"), Collectors.mapping(m -> m.get("Role"), Collectors.toList())));

Это группирует всех пользователей и собирает их роли.

Результат будет:

{User1=[Admin, Integrator], User2=[Auditor, Manager]}
1 голос
/ 28 апреля 2019

Что касается производительности и огромного объема данных, я рекомендую вам избегать использования (хотя само по себе это довольно быстро) и Map::merge способ.

Здесь вы должны придерживаться конструкций, близких к уровню JVM, и for-loops ваши друзья, вот самый простой из известных мне подходов, который может сработать:

final Map<String, Set<String>> newMap = new HashMap<>();

for (Map<String, String> map: list) {                        // iterate the List<Map>
    for (Entry<String, String> entry: map.entrySet()) {      // iterate the entries
        final String key = entry.getKey();                   // get the entry's key
        newMap.computeIfAbsent(key, k -> new HashSet<>());   // compute a new pair
        newMap.get(key).add(entry.getValue());               // add a value in any case
    }
}

Set предотвращает дублирование значений.

Это решение предполагает следующую структуру данных. Небольшие изменения легко применимы к решению выше.

List<Map<String, String>> list = new ArrayList<>();

Map<String, String> map1 = new HashMap<>();
map1.put("User1", "Admin");
map1.put("User2", "Auditor");

Map<String, String> map2 = new HashMap<>();
map2.put("User1", "Integrator");
map2.put("User2", "Manager");
map2.put("User3", "Coffee machine");

list.add(map1);
list.add(map2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...