java.util.ConcurrentModificationException
来源:互联网 发布:macbookpro如何装软件 编辑:程序博客网 时间:2024/06/03 19:00
{ List<String> myList = new ArrayList<String>(); myList.add("1"); myList.add("2"); myList.add("3"); myList.add("4"); myList.add("5"); Iterator<String> it = myList.iterator(); while(it.hasNext()){ String value = it.next(); System.out.println("List Value:"+value); if(value.equals("3")) myList.remove(value);//1 } Map<String,String> myMap = new HashMap<String,String>(); myMap.put("1", "1"); myMap.put("2", "2"); myMap.put("3", "3"); Iterator<String> it1 = myMap.keySet().iterator(); while(it1.hasNext()){ String key = it1.next(); System.out.println("Map Value:"+myMap.get(key)); if(key.equals("2")){ //myMap.put("1","4");//2 myMap.put("4", "4");//3 } System.out.println("Map Value:"+myMap.get(key)); } }System.out.println("----------------"); it1 = myMap.keySet().iterator(); while (it1.hasNext()){ String key = it1.next(); System.out.println("Map Value:"+myMap.get(key)); }
1和3出执行都会发生并发修改异常,是由next()方法抛出的,而2处不会。单独执行2处的结果:
Map Value:1
Map Value:1
Map Value:2
Map Value:2
Map Value:3
Map Value:3
Map Value:4
Map Value:2
Map Value:3
可以发现,Map中的value被覆盖了。但在第一次的遍历中,获取的还是原值,只有重新再获取迭代器,才能获取到被覆盖后的值。
Since we are updating the existing key value in the myMap, its size has not been changed and we are not getting ConcurrentModificationException. Note that the output may differ in your system because HashMap keyset is not ordered like list. If you will uncomment the statement where I am adding a new key-value in the HashMap, it will cause ConcurrentModificationException.
why?
查看源代码:JDK1.8
HashMap:
关键代码
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { private static final long serialVersionUID = 362498820763181265L; transient int modCount; public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount;//1 if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }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(); }//2 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(); } } } final class KeyIterator extends HashIterator implements Iterator<K> { public final K next() { return nextNode().key; } } final Node<K,V> nextNode() { Node<K,V>[] t; Node<K,V> e = next; if (modCount != expectedModCount)//3 throw new ConcurrentModificationException(); if (e == null) throw new NoSuchElementException(); if ((next = (current = e).next) == null && (t = table) != null) { do {} while (index < t.length && (next = t[index++]) == null); } return e; } abstract class HashIterator { Node<K,V> next; // next entry to return Node<K,V> current; // current entry int expectedModCount; // for fast-fail int index; // current slot HashIterator() { expectedModCount = modCount;//4 Node<K,V>[] t = table; current = next = null; index = 0; if (t != null && size > 0) { // advance to first entry do {} while (index < t.length && (next = t[index++]) == null); } }}
1->2->3->4
参考:http://www.journaldev.com/378/java-util-concurrentmodificationexception
- 【ConcurrentModificationException】java.util.ConcurrentModificationException 解决办法
- java.util.ConcurrentModificationException! java.util.ConcurrentModificationException!
- java:java.util.ConcurrentModificationException
- 异常:java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException 解决办法
- java.util.ConcurrentModificationException 异常
- 异常:java.util.ConcurrentModificationException
- 异常:java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException
- java.util.ConcurrentModificationException 异常
- 在其他数都出现k次的数组中找到只出现一次的数
- 各类算法笔试题汇总
- ElasticSearch-深入理解系列4-文档(Document)
- KMP入门
- Android零基础入门第40节:自定义ArrayAdapter
- java.util.ConcurrentModificationException
- 在linux上安装 elasticsearch-php
- 特征类文献---LBP的衍化之道就能创作一篇优秀的文章
- ELasticSearch 深入理解系列5 -索引、类型
- [ Laravel 5.4 文档 ] 综合话题 —— 缓存
- poj-3295-Tautology
- 奶牛喝水最少需要的交换次数
- 双拼输入法使用经验
- 使用任意数量的关键字实参