Слияние Карт, содержащих Наборы, выбрасывает UnsupportedOperationException
Вот код:
private static Map<String, Set<String>> merge(Map<String, Set<String>> m1, Map<String, Set<String>> m2) {
Map<String, Set<String>> mx = new HashMap<String, Set<String>>();
for (Entry<String, Set<String>> entry : m1.entrySet()) {
Set<String> otherMapValue = m2.get(entry.getKey());
if (otherMapValue == null) {
mx.entrySet().add(entry);
} else {
Set<String> merged = new HashSet<String>();
merged.addAll(entry.getValue());
merged.addAll(otherMapValue);
mx.put(entry.getKey(), merged);
}
}
return mx;
}
Это выдает следующую ошибку:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractCollection.add(Unknown Source)
at algorithms.NetworkBuilder.merge(NetworkBuilder.java:86)
at algorithms.NetworkBuilder.build(NetworkBuilder.java:38)
at algorithms.Main.main(Main.java:35)
Я нашел только решения с картами, которые не содержат коллекций, они не сработали для меня, так как мне также нужно объединить наборы, если ключ присутствует на обеих картах.
Я хочу создать новую карту, в которой каждый ключ, содержащий одну или обе карты, сопоставляется с объединением списков, в которые он отображается в исходных двух картах.
2 ответа
Map::entrySet
:
Возвращает представление Set отображений, содержащихся в этой карте. [...] Набор поддерживает удаление элементов, которое удаляет соответствующее отображение с карты с помощью операций Iterator.remove, Set.remove, removeAll, retainAll и clear. Он не поддерживает операции добавления или добавления.
Пытаться mx.put(entry.getKey(), entry.getValue())
вместо mx.entrySet().add(entry)
,
Если вам разрешено использовать сторонние библиотеки, рассмотрите возможность использования Guava Multimap
,
Сравнение
Multimap
s] к карте коллекций
Multimap
s обычно используются в местах, гдеMap<K, Collection<V>>
в противном случае появился бы.
Multimap<String, String> m1 = ...
Multimap<String, String> m2 = ...
m1.putAll(m2); // merged!
Проблема вашего кода в строке
mx.entrySet().add(entry);
Используемый вами набор поддерживает только операции удаления: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
Вы можете изменить эту строку на
mx.put(entry.getKey(), entry.getValue());
Кроме того, ваш метод не учитывает ключи, которые находятся в m2
но не в m1
, Вы можете перебрать m2.entrySet()
также.