黑马程序员技术交流社区

标题: 关于迭代器的疑问 [打印本页]

作者: 张权    时间: 2013-4-21 02:38
标题: 关于迭代器的疑问
本帖最后由 张权 于 2013-4-21 12:07 编辑

import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;

class Demo {
        public static void main(String[] args) {
               
                Collection arrayList=new ArrayList();
                arrayList.add("aa");
                arrayList.add("bb");
                arrayList.add("cc");
                arrayList.add("dd");
                arrayList.add("ee");

        
               
                Iterator iterator=arrayList.iterator();
                while(iterator.hasNext())
                {
                        Object obj = iterator.next();
                /*        if(obj.equals("cc")) {
                                
                                arrayList.remove("cc");//抛异常
                        }*/
                        //下面代码不抛异常, 上面注释代码却会抛异常, 求解释!!!
                        if(obj.equals("dd")) {
                                arrayList.remove("dd");
                        }
                        System.out.println(obj);
                }
                System.out.println(arrayList);
        }
}
问题: 为什么 注释部分代码在做删除元素操作会抛异常, 而没注释的if语句中的代码不会抛异常????   要能说出原因!!!, 谢谢
作者: HM何伟    时间: 2013-4-21 09:27
那是因为你remove之后会得到一个新集合,而下面第二个if中的arryList.remove,还是使用之前原集合的迭代器。修改前是一个集合,修改之后又是一新的集合了,每个集合都会有自已的迭代器。
也就是说上面的代码是拿原集合的迭代器修改集合后,会到得一个新的集合,而你又拿原集合的迭代器对新集合进行迭代。肯定会出问题那。必须拿到新集合的迭代器对新集合进行迭代才不会出错。
作者: 极限冰风    时间: 2013-4-21 10:10
    某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的结果是不确定的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的所有通用 collection 实现)可能选择抛出此异常。执行该操作的迭代器称为快速失败 迭代器,因为迭代器很快就完全失败,而不会冒着在将来某个时间任意发生不确定行为的风险

迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败操作会尽最大努力抛出 ConcurrentModificationException。
因此,为提高此类操作的正确性而编写一个依赖于此异常的程序是错误的做法,正确做法是:ConcurrentModificationException 应该仅用于检测 bug。
所以不能同时操作读取,和删除
作者: lipingan0520    时间: 2013-4-21 10:36
既然是ArrayList集合,使用ListIteratorrw迭代器来遍历输出判断是不是更好呢?
作者: 张权    时间: 2013-4-21 11:13
本帖最后由 张权 于 2013-4-21 11:14 编辑

都没有回答到重点, 我只是想问两者的区别, 我知道不能在获取迭代器后在用迭代器操作集合中的数据, 再用集合去操作数据, 可是我上面的代码, 不是验证了, 我上面有两个if语句, 其中一个是注释掉的, 那部分代码, 如果不注释掉, 注释掉未注释部分的代码, 那么程序会抛异常!!




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