Java ConcurrentModificationException的幻数
我正在使用下面的代码测试集合的Java ConcurrentModificationException的幻数,java,Java,我正在使用下面的代码测试集合的ConcurrentModificationException: public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); for (String s : list) { // i
ConcurrentModificationException
:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
for (String s : list) {
// if (s.equals("a")) { // ConcurrentModificationException!
if (s.equals("b")) { // -->> Magic number, NO Exception, Why?
// if (s.equals("c")) { // ConcurrentModificationException!
list.remove(s);
}
}
System.out.println(list);
}
publicstaticvoidmain(字符串[]args){
ArrayList=新建ArrayList();
列表。添加(“a”);
列表。添加(“b”);
列表。添加(“c”);
用于(字符串s:列表){
//如果(s.equals(“a”){//ConcurrentModificationException!
如果(s.equals(“b”){/-->>幻数,没有例外,为什么?
//如果(s.equals(“c”){//ConcurrentModificationException!
列表。删除;
}
}
系统输出打印项次(列表);
}
我不明白为什么删除“b”是可以的,但其他人不可以?首先要知道的是(如中所述)以下增强的for循环:
for (String s : list) {
// Do something with s
}
相当于:
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String s = it.next();
// Do something with s
}
next()
所做的第一件事是调用checkForComodification()
查看列表是否在我们迭代时被修改:
public E next() {
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
hasNext()
,它将返回false
,因为删除一个元素会导致列表的大小减少一个,并且您的迭代将停止而不调用next()
并引发异常
顺便说一句,所有这些都只是一个实现细节,您不应该依赖它,因为它可能会更改,并且在您迭代时使用它从列表中删除元素。它应该抛出ConcurrentModificationException。您确定您没有在某个地方出错吗?不,我确定。我在JDK 7中进行了测试,在调试模式下运行它,并观察仔细一步,你就会明白为什么边缘值会抛出异常。更进一步,如果你也这样做
list.add(“d”);
,你会注意到删除“c”
也不会再抛出异常。非常感谢这个令人难以置信的回答Hey Florent,那么我可以说这个缺陷是在公共布尔hasNext()中吗{返回游标!=size;}
public E next() {
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}