什么时候会抛出并发修改异常,iterator remove 方法如何工作?
When will be concurrent modification exception will be thrown and how iterator remove method will work?
根据 javadocs,当我们尝试在迭代时对集合进行结构性修改时,将抛出并发修改异常。it.Only迭代器删除方法不会抛出并发修改异常。
我分析过以下几种不会抛出并发修改异常的情况:
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 内部是如何工作的?
第一个实现没有使用迭代器,所以当然不会抛出。只有 Iterator
s 抛出(尽管索引的 for 循环也会被破坏,例如,如果你删除一个元素,然后所有其他元素的索引从你的迭代中移出)。 Java就是没法告诉你。
第二种实现没有改变内容。 var.remove("5")
尝试删除不存在的 字符串 "5"
(列表仅包含整数),因此不会发生任何更改。此外,当 i
是盒装大写字母时 i == 2
是危险的 - I
Integer
;考虑改为 for (int i : var)
。
最后,没有实现保证会抛出 ConcurrentModificationException
;它只是试图这样做来警告您迭代器已损坏。无论是否抛出异常,迭代器 是 被迭代过程中执行的修改破坏,Java 只是想警告你。
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
因此,抛出 CME 的条件是:
- 必须有迭代器(或列表迭代器)
- 您必须对列表进行结构修改,而不是通过迭代器(即添加或删除元素)
而且,也许不那么明显:
- 结构修改后,必须调用结构修改前创建的迭代器上的方法。
即在您对其调用 next()
或 remove()
之前,迭代器不会尝试检测 CME。
根据 javadocs,当我们尝试在迭代时对集合进行结构性修改时,将抛出并发修改异常。it.Only迭代器删除方法不会抛出并发修改异常。
我分析过以下几种不会抛出并发修改异常的情况:
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 内部是如何工作的?
第一个实现没有使用迭代器,所以当然不会抛出。只有 Iterator
s 抛出(尽管索引的 for 循环也会被破坏,例如,如果你删除一个元素,然后所有其他元素的索引从你的迭代中移出)。 Java就是没法告诉你。
第二种实现没有改变内容。 var.remove("5")
尝试删除不存在的 字符串 "5"
(列表仅包含整数),因此不会发生任何更改。此外,当 i
是盒装大写字母时 i == 2
是危险的 - I
Integer
;考虑改为 for (int i : var)
。
最后,没有实现保证会抛出 ConcurrentModificationException
;它只是试图这样做来警告您迭代器已损坏。无论是否抛出异常,迭代器 是 被迭代过程中执行的修改破坏,Java 只是想警告你。
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
因此,抛出 CME 的条件是:
- 必须有迭代器(或列表迭代器)
- 您必须对列表进行结构修改,而不是通过迭代器(即添加或删除元素)
而且,也许不那么明显:
- 结构修改后,必须调用结构修改前创建的迭代器上的方法。
即在您对其调用 next()
或 remove()
之前,迭代器不会尝试检测 CME。