使用iterator.remove时为什么没有错误?

时间:2012-06-11 00:18:51

标签: java exception collections fail-fast

如果我使用Iterator.remove(),一切都很好。如果我使用ArryaList.remove(),我总会收到错误java.util.ConcurrentModificationException

有谁可以指出原因?

4 个答案:

答案 0 :(得分:4)

javadocs说了一切:

  

检测到并发的方法可能抛出此异常   在不允许进行此类修改时修改对象。

     

例如,一个线程通常不允许修改   一个集合,而另一个线程正在迭代它。一般来说,   在这些情况下,迭代的结果是不确定的。   一些迭代器实现(包括所有通用的实现)   由JRE提供的目的集合实现可以选择   如果检测到此行为,则抛出此异常。那个迭代器   这被称为故障快速迭代器,因为它们很快就会失败   干净利落,而不是冒着任意的,非确定性的行为冒险   未来不确定的时间。

你正在修改一个集合并同时迭代它。

答案 1 :(得分:2)

基本上因为它是如何设计的。如果从列表中删除元素,则迭代器不知道它,当它尝试访问列表中的另一个元素时,列表已更改并引发错误。但是如果通过迭代器删除一个元素,那么迭代器就会知道删除,对其数据结构进行适当的调整,然后继续。

答案 2 :(得分:1)

完全来自docs

  

检测到并发的方法可能抛出此异常   在不允许进行此类修改时修改对象。

     

例如,一个线程通常不允许修改   一个集合,而另一个线程正在迭代它。一般来说,   在这些情况下,迭代的结果是不确定的。   一些迭代器实现(包括所有通用的实现)   由JRE提供的目的集合实现可以选择   如果检测到此行为,则抛出此异常。那个迭代器   这被称为故障快速迭代器,因为它们很快就会失败   干净利落,而不是冒着任意的,非确定性的行为冒险   未来不确定的时间。

请查看Class ConcurrentModificationException

答案 3 :(得分:0)

如果在迭代列表时需要删除元素,则应始终使用迭代器。

e.g。

List<String> list = //...
//...
Iterator<String> iter = list.iterator();

while(iter.hasNext()) {
    String str = itr.next();
    //...
    if(/* ... */) {
        iter.remove(str);
    }
}

这是在迭代列表时从列表中删除元素的最安全方法。

注意:您不应该按照以下方式执行操作:

List<String> list = //...
//...
for(String str : list) {
    if(/* ... */) {
        list.remove(); // <-- should not do this
    }
}

大多数情况下,你最终会进入ConcurrentModificationException。增强的for循环使用了引擎盖下的迭代器。并且您手动从列表中删除元素而不是通过迭代器。这就是你得到这个例外的原因。