java.util.ConcurrentModificationException 卧槽

来源:互联网 发布:知名网络言情小说作家 编辑:程序博客网 时间:2024/06/05 11:00

如果你使用了LinkedHashMap的这个构造函数

     public LinkedHashMap(int initialCapacity,                         float loadFactor,                         boolean accessOrder)

并且这样实例化了LinkedHashMap

        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(                11, 0.75f, true);

当然你肯定会遍历这个map,所以或许会这样操作

        Set<String> keySet = map.keySet();        for (String key : keySet) {            String value = map.get(key);        }

不出意外你就会得到如下异常(ps 使用iterator 遍历一样的)

    Exception in thread "main" java.util.ConcurrentModificationException    at java.util.LinkedHashMap$LinkedHashIterator.nextNode(Unknown Source)    at java.util.LinkedHashMap$LinkedKeyIterator.next(Unknown Source)    at LinkHashMapDemo.main(LinkHashMapDemo.java:16)

如何解决

  1. 第三个参数设为false
  2. 使用map.entryKey 遍历

原因

目前还没有深究原因 ,应该是在map.get(key)方法的时候,如果accessOrder(也就是第三个参数)为true的时候回去调用这个方法 afterNodeAccess(e) 方法

源码

 public V get(Object key) {        Node<K,V> e;        if ((e = getNode(hash(key), key)) == null)            return null;        if (accessOrder)            afterNodeAccess(e);        return e.value;    }  void afterNodeAccess(Node<K,V> e) { // move node to last        LinkedHashMap.Entry<K,V> last;        if (accessOrder && (last = tail) != e) {            LinkedHashMap.Entry<K,V> p =                (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;            p.after = null;            if (b == null)                head = a;            else                b.after = a;            if (a != null)                a.before = b;            else                last = b;            if (last == null)                head = p;            else {                p.before = last;                last.after = p;            }            tail = p;            ++modCount;        }    }

linkedHashMap内部应该维护了一个链表 ,会涉及到移动内部的node
所以在get(key) 的时候移动了node 就报异常了,这个应该和遍历的时候去删除元素是一样的道理 。

0 0