объединить два значения карты в Java и, если ключ такой же, добавить значения, которые не перезаписываются в Java 7 или Java 8
Я хочу объединить 2 Map
s, но когда ключ тот же, значения следует добавлять, а не перезаписывать.
Скажем
Map<String, Set<String>> map1 = new HashMap<>();
Set<String> set1 = new HashSet<>();
set1.add("AB");
set1.add("BC");
map1.put("ABCD",set1);
Map<String, Set<String>> map2 = new HashMap<>();
Set<String> set2 =new HashSet<>();
set2.add("CD");
set2.add("EF");
map2.put("ABCD",set2);
map1.putAll(map2);
Итак, здесь ключ такой же. Я знаю, что putAll перезапишет значения, если ключ такой же
Но я ищу результат вроде
{ABCD=[AB,BC,CD,ED]}
Если кто-то может помочь мне решить, буду очень благодарен.
3 ответа
Вы используете функцию слияния, предоставленную для Collectors.toMap
который указывает, что делать со значениями повторяющихся ключей с Streams. Демо
final Map<String, Set<String>> map3 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));
Вы можете применить аналогичный подход, используя Map#merge
. Демо
final Map<String, Set<String>> map3 = new HashMap<>(map1);
map2.forEach((key, val) -> map3.merge(key, val,
(a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));
Вы можете объединить две карты, используя Stream.concat
затем собрать, используя groupingBy
сопоставить ключ и значение как Set.
Map<String, Set<String>> res =
Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
.collect(Collectors.groupingBy(e-> e.getKey(),
Collectors.flatMapping(e -> e.getValue().stream(), Collectors.toSet())));
Примечание: решение использует Java 9+flatMapping
Или
Ты можешь использовать merge
функция карты. Вот слияниеmap2
данные в map1
map2.forEach((key, val) -> map1.merge(key, val, (a, b) -> {a.addAll(b); return a;}));
Выход: {ABCD=[AB, BC, CD, EF]}
Вы можете использовать Stream API для объединения значений одних и тех же ключей. Проверьте,map2
имеет те же ключи от map1
и перебрать их и объединить значения вместе, используя addAll()
map1.entrySet().stream().filter(entry -> map2.containsKey(entry.getKey()))
.forEach(entry -> entry.getValue().addAll(map2.get(entry.getKey())));
, main
функция
public static void main(String[] args) {
Map<String, Set<String>> map1 = new HashMap<>();
Set<String> set1 = new HashSet<>();
set1.add("AB");
set1.add("BC");
map1.put("ABCD", set1);
Map<String, Set<String>> map2 = new HashMap<>();
Set<String> set2 = new HashSet<>();
set2.add("CD");
set2.add("EF");
map2.put("ABCD", set2);
map1.entrySet()
.stream()
.filter(entry -> map2.containsKey(entry.getKey()))
.forEach(entry -> entry.getValue().addAll(map2.get(entry.getKey())));
System.out.println(map1);
}
, output
{ABCD=[AB, BC, CD, EF]}