A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 黄奕豪 于 2012-5-25 11:11 编辑

不多说,看代码,为什么同样是定义一个Iterator的实现子类,放在不一样的位置编译就失败呢?
之前因为未看后面视频才问出此问题,在此自问自答一下吧:因为迭代器迭代过程也有增删改查的动作,集合对象本身也有增删改查的动作,两个动作不能并发执行,就像相同的货,我刚接上级报告说要去仓库取那么多货,你先我之前就把货取走了,闹矛盾了~~具体闹矛盾过程可参照下楼理解,下楼兄弟给出了源码~得了~!~谢谢各位~~~
  1. import java.util.*;
  2. class ArrayListDemo
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 ArrayList sl = new ArrayList();               
  7.                 Iterator it = sl.iterator();//放这里编译能过,但是运行时就抛出错误:Exception in thread "main" java.util.ConcurrentModificationException
  8.                
  9.                 sl.add("12");
  10.                 sl.add("34");
  11.                 sl.add("56");
  12.                 sl.add("78");

  13.                 //Iterator it = sl.iterator();//放这里可以
  14.                 sop(it.next());
  15.                 sop(sl);
  16.                
  17.         }
  18.         public static void sop(Object str)//简化输出代码
  19.         {
  20.                 System.out.println(str);
  21.         }
  22. }
复制代码

6 个回复

倒序浏览
你获取到了迭代器, 在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常(并发修改)
所以在迭代时,只能用迭代器的方法操作元素,Iterator方法是有限的。
只能对元素进行判断,删除,取出。
顺便提一点:
对于List如果想要其他的操作,如:添加,修改等,可以使用其子接口:ListIterator。

回复 使用道具 举报
LZ这里犯了几个错误
1.List<String> list = new ArrayList<String>();  建议这么写
2.在使用迭代器之前,必须保证集合的元素没有被修改过,
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
这段代码在next()函数中被调用,这里的modCount,你每一次调用add方法都会使得modCount++,而你的ExpectedModCount在前面就定义好了,所以这里会抛出异常

记住在创建迭代器以后紧接着使用它就不会出现这个问题了。

顺便给出next()的源码
        public E next() {
            checkForComodification();
            try {
                E next = get(cursor);
                lastRet = cursor++;
                return next;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }
lz也可以自己查阅
回复 使用道具 举报
调用迭代器的next方法时,需要做一个判断
while(it.hasNext()){
sop(it.next());
}
回复 使用道具 举报
秦冲 发表于 2012-5-25 03:08
你获取到了迭代器, 在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModifica ...

你获取到了迭代器, 在迭代时,不可以通过集合对象的方法操作集合中的元素。
我这里没有用集合对象的方法操作集合中的元素啊,我是用ArrayList集合对象的方法iterator()获取了一个ListIterator对象,然后利用多态传给it,用的是it.next()操作元素~~~这里只是一个简单的取出打印动作!我是搞不明白为什么声明放在不同地方就运行不起来~~~
回复 使用道具 举报
闾丘日月 发表于 2012-5-25 03:18
LZ这里犯了几个错误
1.List list = new ArrayList();  建议这么写
2.在使用迭代器之前,必须保证集合的元素 ...

就是说集合对象里面还有个参数改变计数器,迭代器定义的时候就把这个值赋值给了迭代器,然后迭代器里面的计数器是final的,如果最后调用的时候集合对象里面的计数器跟迭代器里面的计数器对不上号就会报出那个什么什么并发修改异常~~~是这样么?了然,那不知道我如果不是增元素,而是删元素,行不行~~我去实验下!!
回复 使用道具 举报
黄奕豪 发表于 2012-5-25 10:04
就是说集合对象里面还有个参数改变计数器,迭代器定义的时候就把这个值赋值给了迭代器,然后迭代器里面的 ...

:lol不行,看来真的是参数改变的计数器,而不是单只加的计数器~~~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马