NIN*_*OOP 1 java collections iterator
这是对我之前的问题的跟进:
集合 - Iterator.remove() 与 Collection.remove()
下面的两段代码,显然只有一行不同,但一个抛出异常,另一个不抛出。你能解释一下区别吗?
List<String> list = new ArrayList<String>
(Arrays.asList("noob1","noob2","noob3"));
System.out.println(list);
for (String str : list) {
if (str.equals("noob2")) {
list.remove(str);
}
}
Run Code Online (Sandbox Code Playgroud)
运行良好,但如果我将条件更改为
if (!str.equals("noob2"))
Run Code Online (Sandbox Code Playgroud)
代码抛出异常!
在这种情况下会发生什么是您正在删除第二个列表元素。
List<String> list = new ArrayList<String>
(Arrays.asList("noob1", "noob2", "noob3", "noob4"));
System.out.println(list);
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
String str = iterator.next();
if (str.equals("noob3")) {
System.out.println("Checking "+str);
list.remove(str);
}
}
System.out.println(list);
Run Code Online (Sandbox Code Playgroud)
印刷
[noob1, noob2, noob3, noob4]
Checking noob1
Checking noob2
Checking noob3
[noob1, noob2, noob4]
Run Code Online (Sandbox Code Playgroud)
通过删除倒数第二个元素,您已将大小减小到您迭代的元素数量。
// from ArrayList.Itr
public boolean hasNext() {
return cursor != size;
}
Run Code Online (Sandbox Code Playgroud)
这会导致循环在 中执行并发修改检查之前提前退出next()。如果您删除任何其他元素,next()则调用并获得 CME。
顺便说一句,也绕过检查的东西是
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
String str = iterator.next();
System.out.println("Checking "+str);
if (str.equals("noob2")) {
list.remove("noob1");
list.remove("noob3");
}
}
Run Code Online (Sandbox Code Playgroud)
只要集合的大小与它达到的索引相同,就不会执行检查。