我有下面的类,用于检查使用 foreach 循环从数组列表中删除对象
import java.util.ArrayList;
public class CheckArrayList {
/**
* @return the a
*/
public int getA() {
return a;
}
/**
* @param a
* the a to set
*/
public void setA(int a) {
this.a = a;
}
/**
* @return the b
*/
public int getB() {
return b;
}
/**
* @param b
* the b to set
*/
public void setB(int b) {
this.b = b;
}
int a;
int b;
public static void main(String[] args) {
try {
CheckArrayList checkArrayList1 = new CheckArrayList();
checkArrayList1.setA(10);
checkArrayList1.setB(20);
CheckArrayList checkArrayList2 = new CheckArrayList();
checkArrayList2.setA(30);
checkArrayList2.setB(40);
ArrayList<CheckArrayList> aList = new ArrayList<CheckArrayList>();
aList.add(checkArrayList1);
aList.add(checkArrayList2);
System.out.println("size of list before iterate = " + aList.size());
for (CheckArrayList checkArrayList : aList) {
aList.remove(checkArrayList);
System.out.println("inside loop");
}
System.out.println("size of list after iterate = " + aList.size());
} catch (Exception e) {
e.printStackTrace();
}
}
}
在执行上述操作时,没有显示任何异常,但它只进入循环一次。
如果我向 ist 添加一个对象并执行相同的操作,它会显示 java.util.ConcurrentModificationException
import java.util.ArrayList;
public class CheckArrayList {
/**
* @return the a
*/
public int getA() {
return a;
}
/**
* @param a
* the a to set
*/
public void setA(int a) {
this.a = a;
}
/**
* @return the b
*/
public int getB() {
return b;
}
/**
* @param b
* the b to set
*/
public void setB(int b) {
this.b = b;
}
int a;
int b;
public static void main(String[] args) {
try {
CheckArrayList checkArrayList1 = new CheckArrayList();
checkArrayList1.setA(10);
checkArrayList1.setB(20);
CheckArrayList checkArrayList2 = new CheckArrayList();
checkArrayList2.setA(30);
checkArrayList2.setB(40);
CheckArrayList checkArrayList3 = new CheckArrayList();
checkArrayList3.setA(30);
checkArrayList3.setB(40);
ArrayList<CheckArrayList> aList = new ArrayList<CheckArrayList>();
aList.add(checkArrayList1);
aList.add(checkArrayList2);
aList.add(checkArrayList3);
System.out.println("size of list before iterate = " + aList.size());
for (CheckArrayList checkArrayList : aList) {
aList.remove(checkArrayList);
System.out.println("inside loop");
}
System.out.println("size of list after iterate = " + aList.size());
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果arralist大小等于2,为什么它不显示异常?
最佳答案
要回答为什么它不会在 2 个元素上抛出错误,您必须查看 foreach 循环实际执行的操作。for(Type some:myList)
编译为如下内容:
Iterator<Type> iter = myList.iterator();
while(iter.hasNext()){
Type something= iter.next()
//your code
}
现在查看ArrayList
的源代码以了解实际实现。 hasNext()
的代码是:
return cursor != size; //cursor is the current position in the list
因此,当您删除循环中的元素时,size
现在为 1。当它查看是否有更多元素时,它将返回 false,因为它认为该元素位于循环的末尾。 ArrayList,并在此时停止执行循环。
现在看看 next()
的代码:
public E next() {
checkForComodification();
//more code
}
这是实际检查修改的地方,因此当 size 为 3 时,它将执行第二次迭代,当调用 next()
获取第二个元素时,它将抛出异常因为您已在迭代器之外修改了 ArrayList。
关于java - 仅当列表大小大于 2 时,才会发生使用 foreach 从 arraylist 中删除对象的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20040015/