HashMap.values().addAll()异常



问题:在使用一个Collection.addAll()方法时报告UnsupportedOperationException。追溯原因发现该collection是来自于hashMap.values()。


分析原因:通过查看源代码,发现hashMap.values()实现如下:

   //HashMap.java
   public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null ? vs : (values = new Values()));
    }
    
      private final class Values extends AbstractCollection<V> {
        public Iterator<V> iterator() {
            return newValueIterator();
        }
        public int size() {
            return size;
        }
        public boolean contains(Object o) {
            return containsValue(o);
        }
        public void clear() {
            HashMap.this.clear();
        }
    }
    
    //其中values的定义如下:AbstractMap.java
      transient volatile Collection<V> values = null;
       public Collection<V> values() {
        if (values == null) {
            values = new AbstractCollection<V>() {
                public Iterator<V> iterator() {
                    return new Iterator<V>() {
                        private Iterator<Entry<K,V>> i = entrySet().iterator();

                        public boolean hasNext() {
                            return i.hasNext();
                        }

                        public V next() {
                            return i.next().getValue();
                        }

                        public void remove() {
                            i.remove();
                        }
                    };
                }

                public int size() {
                    return AbstractMap.this.size();
                }

                public boolean isEmpty() {
                    return AbstractMap.this.isEmpty();
                }

                public void clear() {
                    AbstractMap.this.clear();
                }

                public boolean contains(Object v) {
                    return AbstractMap.this.containsValue(v);
                }
            };
        }
        return values;
    }

从上面代码看到,hashMap.values()先看values是否为空:

  • 如果不为空,则直接返回values。values是在在AbstractMap中定义的,初始化时new了一个AbstractCollection,并实现了若干方法,但是并没有实现all()和addAll()方法。

  • 如果为空,则new一个内部实现类Values。Values同样没有实现AbstractCollection的没有实现all()和addAll()方法。

再来看一下AbstractCollection的add()和addAll()方法:

 //AbstractCollection.java
 public boolean add(E e) {
        throw new UnsupportedOperationException();
    }
    
 public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

可以看到,add方法的实现是直接抛出UnsupportedOperationException,addAll方法调用add方法,也间接抛出异常,同样的,HashMap.values()调用add()和addAll()也会抛出异常。


结论:通过以上分析,明确了HashMap.values()调用add()和addAll()抛出异常的原因。也告诉我们在实际使用中,要注意避免直接使用HashMap.values().add()和HashMap.values().addAll()。




本文出自 “winger” 博客,谢绝转载!

你可能感兴趣的:(HashMap,values(),add())