map.keySet()踩坑

问题:

    以前学习时都知道Arrays.asList()生成的列表不支持增删操作,没想到一直忽略了map的keySet()方法返回的集合,今天偷懒直接用了Set<String> set = map.keySet()并且做了add操作。记录下报错和原因。

注:对keySet的修改也会影响原map

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractCollection.add(AbstractCollection.java:262)
	at Demo.main(Demo.java:7)

源码

map.keySet()返回keySet类型的集合

System.out.println(map.keySet().getClass().toString());
// output
class java.util.HashMap$KeySet

hashmap源码中keySet继承abstractSet并且没有add和remove操作

public Set<K> keySet() {
        Set<K> ks = keySet;
        if (ks == null) {
            ks = new KeySet();
            keySet = ks;
        }
        return ks;
    }

final class KeySet extends AbstractSet<K> {
    public final int size()                 { return size; }
    public final void clear()               { HashMap.this.clear(); }
    public final Iterator<K> iterator()     { return new KeyIterator(); }
    public final boolean contains(Object o) { return containsKey(o); }
    public final boolean remove(Object key) {
        return removeNode(hash(key), key, null, false, true) != null;
    }
    public final Spliterator<K> spliterator() {
        return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
    }
    public final void forEach(Consumer<? super K> action) {
        Node<K,V>[] tab;
        if (action == null)
            throw new NullPointerException();
        if (size > 0 && (tab = table) != null) {
            int mc = modCount;
            for (int i = 0; i < tab.length; ++i) {
                for (Node<K,V> e = tab[i]; e != null; e = e.next)
                    action.accept(e.key);
            }
            if (modCount != mc)
                throw new ConcurrentModificationException();
        }
    }
}
上一篇:java 8 日期操作


下一篇:Ubuntu12.04环境搭建遇到的问题和建议(一个)