根据javadocs,当我们尝试在迭代时对结构进行结构修改时,会抛出并发修改异常。只有迭代器remove方法才会抛出并发修改异常。
我已经分析了以下不会抛出并发修改异常的情况:
List<Integer> var=new ArrayList<Integer>();
var.add(3);
var.add(2);
var.add(5);
第一案:
for(int i = 0; i<var.size(); i++){
System.out.println(var.get(i));
var.remove(i);
}
第二案:
for(Integer i:var){
System.out.println(i);
if(i==2){
var.remove("5");
}
}
1)任何人都可以解释一下这些案例是如何不引起Conncurrent Modification Exception的吗? 2)有谁能告诉iterator.remove内部是如何工作的?
答案 0 :(得分:1)
第一个实现不使用迭代器,所以它当然不会抛出。它只会抛出Iterator
(尽管即使是索引的for循环也会被破坏,例如,如果删除一个元素,然后所有其他元素的索引都会从迭代中移出)。 Java只是无法告诉你。
第二种实现不是改变内容。 var.remove("5")
尝试删除不存在的字符串 "5"
(列表中只包含整数),因此不会发生任何更改。此外,当i == 2
是盒装资本时,i
会很危险 - I
Integer
;考虑改为for (int i : var)
。
最后,没有实现保证会抛出ConcurrentModificationException
;它只是试图这样做来警告你你的迭代器已经被破坏了。无论是否抛出异常,迭代器 都会因迭代过程中执行的修改而被破坏,Java只是试图警告你。
答案 1 :(得分:0)
此类的迭代器和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法之外,迭代器将抛出一个ConcurrentModificationException。
因此,CME将被抛出的条件是:
而且,也许不那么明显:
即。迭代器在您上面调用next()
或remove()
之前不会尝试检测CME。