【问题标题】:java.lang.UnsupportedOperationException when combining two Sets组合两个 Set 时出现 java.lang.UnsupportedOperationException
【发布时间】:2013-11-13 10:03:35
【问题描述】:

我有 2 个不同的 HashMap 实例

我想合并两个 HashMap 的键集;

代码:

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

例外:

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

我没有收到编译警告或错误。

从 java doc 这应该可以工作。即使添加的集合也是一个集合:

boolean addAll(Collection c)

将指定集合中的所有元素添加到此集合中,如果 它们不存在(可选操作)。如果指定 collection 也是一个集合,addAll 操作有效地修改了 这个集合使得它的值是两个集合的并集。行为 如果指定的集合被修改,则此操作的未定义 操作进行中。

【问题讨论】:

  • 请注意,如果其中一组是不可变的,也会发生这种情况

标签: java collections set


【解决方案1】:

如果您查看 HashMap#keySet() 方法的文档,您会得到答案(重点是我的)。

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      请阅读documentation

      【讨论】:

        【解决方案4】:

        以上所有答案都是正确的。如果你还想知道具体的实现细节(jdk 8)

        hashMap1.keySet() returns a KeySet&lt;E&gt;

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

        在 AbstractCollection 中,

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

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

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            猜你喜欢
            • 2021-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-11
            • 2019-10-05
            相关资源
            最近更新 更多