问题背景
业务中想要将一个set中的元素添加到一个keySet中,以为可以类似List一样,调用java.util.Collection#addAll(Collection<? extends E> c)
,如
1 | // 将一个list的元素加到另一个list中 |
于是写成1
2
3
4// 从map获取keySet
Set<String> videoWxhSet = resolutionMap.keySet();
// 将一个set加到另一个set中
videoWxhSet.addAll(picWxhSet);
编译没有问题,运行报错了,显示该操作不被支持
Caused by: java.lang.UnsupportedOperationException
at java.util.AbstractCollection.add(AbstractCollection.java:262)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
原因
源码分析
keySet方法返回了一个HashMap.KeySet
对象,是HashMap
的内部类。
keySet
方法并未实现add/addAll等方法
而Collection#addAll
方法在未实现的情况下调用会抛出UnsupportedOperationException
异常。
查看HashMap源码里keySet()方法描述
Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator’s own remove operation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.
Returns: a set view of the keys contained in this map
简单翻译下
keySet返回的是map中所有的key,对map的修改会影响到keySet,反之对keySet的修改也会影响到map。所以set支持元素移除,但不支持元素添加
验证
1 | public static void main(String[] args) { |
可以看到,对keySet的修改会同步到map。所以对keySet的添加是有问题的,因为添加的key在map里没有对应的value
解决方案
重新new HashSet(),将两个set丢进去即可
1 | HashSet<String> allWxhSet = new HashSet<>(); |