您的位置:首页 > 其它

使用迭代器时为什么不能用集合删除元素的方法

2017-06-29 19:57 411 查看
原文地址:http://www.cnblogs.com/YYCat/p/4675084.html

由该链接引发的思考:http://bbs.itheima.com/forum.php?mod=viewthread&tid=26270&mobile=1

看到这篇文章后,一副似懂非懂的样子,果断将楼主的代码拷贝到eclipse中运行了下,果然发现了些问题。

经过测试,发现总是在当集合中倒数第二个满足条件时程序才可以正常运行,否则,就会抛出ConcurrentModificationException异常

然后,我在while{it.hasNext()){和String str = (Strign)it.next()处设置了断点:——经行debug查找:



当程序抛出异常时总是执行到it.next()处发生:API中提到(在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对

列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。),也就是当发生了

如下图中modCount(记录了对集合修改的次数)的值不等于expectedModCount(通过迭代器对集合修改的次数)的值会抛异常。

反之,如果程序仍能正常运行的话,那么唯一的解释就是,该语句并没有执行到next这条语句块中

程序运行后发现如图:



也就是size的值等于cursor的值时,程序不会在执行while当中的内容,因此不会发生异常就结束。即——该判断标准中it.hasNext()

是否返回true的标准就是size!=cursor时成立。

最后附上网上的判断——

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性

P.S.

自我感觉就像对账一样。总奖励有10万,A持有所有的奖励领取记录(共领取了4万),B持有记录的备份。B对账的时候,突然小明从A那取走1万,A的记录更新了但B没有。

B对账的时候发现奖励还剩5万,有1万不在账上。他赶紧上报(抛异常)。(都是假设)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐