java.util.ConcurrentModification…

来源:互联网 发布:js只能输入以-数字开头 编辑:程序博客网 时间:2024/06/05 11:30

错误代码:

public static void main(String[] args) {
  List list = newArrayList();
  list.add("1");
  list.add("2");
  list.add("3");
  list.add("4");
  Iterator it =list.iterator();
  while (it.hasNext()) {
   if(it.next().equals("1")){
    list.remove("1");
   }
   
  }
 }

抛出异常:

java.util.ConcurrentModificationException
 atjava.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
 atjava.util.AbstractList$Itr.next(AbstractList.java:343)
 atcom.baihe.util.ZnplUtil.main(ZnplUtil.java:256)

原因:

在内部类Itr中,有一个字段expectedModCount ,初始化

时等于modCount,即当我们调用list.iterator()返回迭代器时,该字段被初始化为等于modCount。在类Itr中next/remove方法都有调用checkForComodification()方法,在该方法中检测modCount==expectedModCount,如果不相当则抛出异常ConcurrentModificationException。
前面说过,在集合的修改操作(add/remove)中,都对modCount操作了。
在看看刚开始提出的那段代码,在迭代过程中,执行list.remove(val),使得modCount+1,当下一次循环时,执行it.next(),checkForComodification方法发现modCount !=expectedModCount,则抛出异常。

解决办法:

如果想要在迭代的过程中,执行删除元素操作怎么办?
再来看看内部类Itr的remove()方法,在删除元素后,有这么一句expectedModCount =modCount,同步修改expectedModCount的值。所以,如果需要在使用迭代器迭代时,删除元素,可以使用迭代器提供的remove方法。对于add操作,则在整个迭代器迭代过程中是不允许的。其他集合(Map/Set)使用迭代器迭代也是一样。



0 0