java遍历集合删除特定元素的 java.util.ConcurrentModificationException异常
来源:互联网 发布:知世与艾利欧 艾知 编辑:程序博客网 时间:2024/04/30 00:58
看一段代码:
for (SecurityPsn psn : psnList) {
if(StringUtils.isBlank(psn.getCertCode())){
psnList.remove(psn);
}
}
该代码会抛出java.util.ConcurrentModificationException异常
正确代码为:
Iterator<SecurityPsn> iter = psnList.iterator();
while (iter.hasNext()) {
SecurityPsn psn = iter.next();
if (StringUtils.isBlank(psn.getCertCode())) {
iter.remove();
}
}
解决办法为:如果不是Iterator迭代方式,则修改迭代方式为Iterator()方式,采用iterator.remove();而不直接通过map.remove();
原因:当修改的个数跟期望修改的个数不相等时抛出此异常。
如果改成:
for (int i=0;i<psnList.size();i++ ) {
if(StringUtils.isBlank(psnList.get(i).getCertCode())){
psnList.remove(psn);
}
}
虽然不报上述错误,但结果不准确,且最后一个下标可能会越界。
因为集合的大小是动态变化的,当你删除一个元素之后,元素中的序号又重新排列,原来第二个应该删除的元素现在排在了第一个元素的位置,真正删除的却是第三个元素,依次类推,删除的是第一个、第三个、第五个,所以第二种正确的做法为:
for (int i=0;i<psnList.size();i++ ) {
if(StringUtils.isBlank(psnList.get(i).getCertCode())){
psnList.remove(psnList.get(i));
i--;
}
}
源码分析:
final Entry<K, V> nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); // 抛出异常 Entry<K, V> e = current = next; if (e == null) throw new NoSuchElementException(); if ((next = e.next) == null) { Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } return e; } ...
查看remove()方法代码如下:
/** * Removes the mapping for the specified key from this map if present. * * @param key key whose mapping is to be removed from the map * @return the previous value associated with <tt>key</tt>, or * <tt>null</tt> if there was no mapping for <tt>key</tt>. * (A <tt>null</tt> return can also indicate that the map * previously associated <tt>null</tt> with <tt>key</tt>.) */ public V remove(Object key) { Entry<K,V> e = removeEntryForKey(key); return (e == null ? null : e.value); } /** * Removes and returns the entry associated with the specified key * in the HashMap. Returns null if the HashMap contains no mapping * for this key. */ final Entry<K,V> removeEntryForKey(Object key) { int hash = (key == null) ? 0 : hash(key.hashCode()); int i = indexFor(hash, table.length); Entry<K,V> prev = table[i]; Entry<K,V> e = prev; while (e != null) { Entry<K,V> next = e.next; Object k; if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { modCount++; size--; if (prev == e) table[i] = next; else prev.next = next; e.recordRemoval(this); return e; } prev = e; e = next; } return e; }
发现,其中有modCount++操作。
modCount表示修改的次数,而并没有改变其exceptedmodCount;
接下来看看iterator.remove()方法:(java.util.Hashtable.Enumerator.remove())
public void remove() { if (!iterator) throw new UnsupportedOperationException(); if (lastReturned == null) throw new IllegalStateException("Hashtable Enumerator"); if (modCount != expectedModCount) throw new ConcurrentModificationException(); synchronized(Hashtable.this) { Entry[] tab = Hashtable.this.table; int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length; for (Entry<K,V> e = tab[index], prev = null; e != null; prev = e, e = e.next) { if (e == lastReturned) { modCount++; expectedModCount++; if (prev == null) tab[index] = e.next; else prev.next = e.next; count--; lastReturned = null; return; } } throw new ConcurrentModificationException(); } } }
而此删除元素的方法,将modCount自增的同时将exceptedModCount同样自增。也就不会抛出异常。
- java遍历集合删除特定元素的 java.util.ConcurrentModificationException异常
- JAVA集合中删除元素时的java.util.ConcurrentModificationException
- 遍历集合时删除元素,抛出java.util.ConcurrentModificationException的解决办法
- JAVA List 一边遍历一边删除元素,报java.util.ConcurrentModificationException异常
- 集合遍历 java.util.ConcurrentModificationException
- java 遍历list、set时 删除元素 java.util.ConcurrentModificationException
- ArrayList循环遍历并删除元素时报java.util.ConcurrentModificationException异常
- java.util.ConcurrentModificationException ,遍历集合并同时修改集合,并发造成的异常解决办法
- 关于迭代器的在集合遍历中发生的并发修改异常(java.util.ConcurrentModificationException
- 遍历集合时出现的异常Exception in thread "main" java.util.ConcurrentModificationException
- 遍历集合时出现的异常Exception in thread "main" java.util.ConcurrentModificationException
- java set 删除元素 java.util.ConcurrentModificationException
- 关于迭代集合同时删除元素报错的问题java.util.ConcurrentModificationException
- 遍历Map时抛出java.util.ConcurrentModificationException异常的解决办法
- 遍历Map时抛出java.util.ConcurrentModificationException异常的解决办法
- java.util.ConcurrentModificationException 集合remove异常
- java.util.ConcurrentModificationException 与集合删除
- 异常:java.util.ConcurrentModificationException
- 国内首家苹果iBeacon系统“水滴”启动商用
- 下次有人不会配unity 安卓环境,就让他看看这个吧
- android使用notifyDataSetChanged()方法更新数据失效,adapter的数据更新了,但是ListView的内容没有更新;
- iOS 学习框架图
- 蓝桥杯-基础练习-01字串
- java遍历集合删除特定元素的 java.util.ConcurrentModificationException异常
- spring回滚事务
- Android开发之深入理解Intent
- CSS3 新属性
- Error:Execution failed for task ‘:app:dexDebug’. > com.android.ide.common.process.ProcessException:
- C++的精髓——虚函数
- 怎么设置电脑锁屏不断网
- Hbase存储格式
- Apache Tomcat开机后台启动