Question: in the use of a Collection. The addAll report UnsupportedOperationException () method. The traceability reveals that the collection came from HashMap.values ().

Why: Looking at the source code, we find that HashMap.values () implements the following:

//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(); }} 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 () first looks to see if values are null:

If it is not null, values are returned directly. Values are defined in AbstractMap, initializes an AbstractCollection and implements several methods, but not all() and addAll() methods.

If empty, new an internal implementation class Values. Values also does not implement AbstractCollection without implementing all() and addAll() methods.

Consider AbstractCollection’s add() and addAll() methods again:

//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;
}

As you can see, the add method of implementation is directly throw UnsupportedOperationException, addAll method calls the add method, also indirectly throws an exception, in the same way, a HashMap. Values () call the add () and addAll () will throw an exception.

Conclusion: From the above analysis, it is clear why hashMap.values () calls add() and addAll() throw exceptions. It also tells us to be careful to avoid using hashMap.values ().add() and hashMap.values ().addAll() directly in practice. Also: hashMap.vKeySet (), hashMap.entrySet () calls the add() and addAll() methods.