如果你使用了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)
如何解决
- 第三个参数设为false
- 使用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 就报异常了,这个应该和遍历的时候去删除元素是一样的道理 。