黑马程序员技术交流社区

标题: 在遍历集合时向集合中添加元素出现的问题? [打印本页]

作者: 弘一    时间: 2013-12-25 08:07
标题: 在遍历集合时向集合中添加元素出现的问题?
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class HelloWorld {
public static void main(String[] args) {
     // 创建集合对象
    List list = new ArrayList();
    // 添加元素
    list.add("qq");
    list.add("ww");
    list.add("ee");
    Iterator it = list.iterator();
    while (it.hasNext()) {
    String s = (String) it.next();
    if ("qq".equals(s)) {
      list.add("ao");
     }
   }
   System.out.println("list:" + list);
  }
}

报错是:Exception in thread "main" java.util.ConcurrentModificationException
请问这是什么意思?怎样会出现这种问题的?那我应该如何解决?

作者: just_nnnnx    时间: 2013-12-25 08:28
  某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的结果是不确定的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的所有通用 collection 实现)可能选择抛出此异常。执行该操作的迭代器称为快速失败 迭代器,因为迭代器很快就完全失败,而不会冒着在将来某个时间任意发生不确定行为的风险。
  所以说,是不可以一边迭代一边往集合里加入新的元素的,你可以创建一个StringBuilder对象,往里面添加字符串就行了

作者: 恨死我了    时间: 2013-12-25 09:45
从API中可以看到List等Collection的实现并没有同步化,如果在多 线程应用程序中出现同时访问,而且出现修改操作的时候都要求外部操作同步化;调用Iterator操作获得的Iterator对象在多线程修改的List时 候也自动失效,并抛出java.util.ConcurrentModificationException。这种实现机制是fail-fast,对外部 的修改并不能提供任何保证。
你可以采用Iterator的扩展方法ListIterator方法,往里面添加字符串就行了

作者: 闫志军    时间: 2013-12-25 09:51
有一个列表迭代器,listIterator ,,,,他在迭代过程中是允许添加或删除元素的。是Itrator的子接口。
作者: 776699    时间: 2013-12-25 10:06
执行add(Object o)方法之后,modCount和expectedModCount不相等了。然后当代码执行到next()方法时,判断了checkForComodification(),发现两个数值不等,就抛出了该Exception
作者: 恩恩    时间: 2013-12-25 11:21
当你在遍历一个集合的时候是不能够对集合里面的数据进行操作的,如果你一定要进行操作,那么最好建议是在新建一个集合,然后把值赋值到另外一个集合,对那个集合进行操作。
你可以比较一下下面这两个代码块

public void operate(List list){
        for (Iterator it = list.iterator(); it.hasNext();) {
            String str = (String)it.next();
            if (str.equals("chengang")){
                list.remove(str);
            }
        }
    }//因为list在循环中的时候是不可以删除它的元素的这些写就没有问题,你可以试下。。

for (Iterator it = list.iterator(); it.hasNext();) {
            String str = (String)it.next();
            if (str.equals("chengang")){
                it.remove();
           }
        }
作者: 程玉习    时间: 2013-12-25 12:21
迭代器Iterator运行时是一个独立的线程,Exception in thread "main" java.util.ConcurrentModificationException是主线程中当前集合被修改异常。Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以 Iterator 会马上抛出java.util.ConcurrentModificationException 异常,不能直接添加但可以用remove()方法,添加可以新建一个集合
作者: kun1990    时间: 2013-12-25 18:22
Exception in thread "main" java.util.ConcurrentModificationException这是属于并发修改异常,因为你修改了你集合,但是迭代器是跟你的集合来变化的,但是你修改了集合而没有修改迭代器,所以编译时就抛出了异常
作者: 木木赤赤    时间: 2013-12-27 10:43
在迭代时,不可以通过集合对象的方法操作集合中的元素,
因为会发生ConcurrentModificationException异常。

所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,
只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator.





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2