49

I have 2 different instances of HashMap

I want to merge the keysets of both HashMaps;

Code:

Set<String> mySet = hashMap1.keySet();
mySet.addAll(hashMap2.keySet());

Exception:

java.lang.UnsupportedOperationException
    at java.util.AbstractCollection.add(AbstractCollection.java:238)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:322)

I don't get a compile warning or error.

From java doc this should work. Even if the added collection is also a set:

boolean addAll(Collection c)

Adds all of the elements in the specified collection to this set if they're not already present (optional operation). If the specified collection is also a set, the addAll operation effectively modifies this set so that its value is the union of the two sets. The behavior of this operation is undefined if the specified collection is modified while the operation is in progress.

4

5 回答 5

57

如果您查看该HashMap#keySet()方法的文档,您会得到答案(强调我的)。

返回此映射中包含的键的 Set 视图。集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改了映射(通过迭代器自己的删除操作除外),则迭代的结果是不确定的。该集合支持元素移除,即通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。它不支持 add 或 addAll 操作。

因此,您需要创建一个新集合并将所有元素添加到其中,而不是将元素添加SetkeySet().

于 2013-11-13T10:06:04.743 回答
34

的结果keySet()不支持向其添加元素。

如果您不尝试修改hashMap1,而只是想要一个包含两个地图键并集的集合,请尝试:

Set<String> mySet = new HashSet<String>();
mySet.addAll(hashMap1.keySet());
mySet.addAll(hashMap2.keySet());
于 2013-11-13T10:05:45.577 回答
1

不支持来自 map.keySet() 的 Set 的性质。它仅支持 remove、removeAll、retainAll 和 clear 操作。

请阅读文档

于 2013-11-13T10:06:06.397 回答
1

以上所有答案都是正确的。如果您仍然想知道确切的实现细节(jdk 8)

hashMap1.keySet() returns a KeySet<E>

KeySet<E>   extends AbstractSet<E>
AbstractSet<E> extends AbstractCollection<E> 

在 AbstractCollection 中,

public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

addAll() calls add()这就是为什么你得到一个UOException

于 2017-08-03T08:26:59.453 回答
0

只需使用 Map 的键创建您自己的 Set,如下所示:

Set set = new HashSet(map.keySet()); 

然后你可以添加任何你想要的东西。

于 2020-10-07T19:26:13.747 回答