我尝试过以下两种情况:
ArrayList arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("1")) {
arrayList.remove(0);
}
}
第一个场景输出是:
---->1
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at Test.main(Test.java:83)
可能导致ConcurrentModificationException
例外是因为我在尝试修改集合时仍在进行迭代。
在第二种情况下,我将if()
条件从value.equals("1")
更改为value.equals("2")
,程序不会抛出任何错误。
ArrayList arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
arrayList.remove(0);
}
}
第二种情景输出是:
---->1
---->2
在这两种情况下,我的程序都没有达到第3个元素(值:3)。
能帮助我理解这个问题吗?
答案 0 :(得分:4)
问题是你要从索引0前面的列表中删除元素。而不是从列表中删除使用 iterator.remove()方法。有关详细信息,请阅读this。
程序代码 -
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
iterator.remove();
}
}
为什么列表不返回最后一个元素?
回答 -
您要从列表中删除元素,并且您已针对相同列表执行迭代器操作。最后 iterator.hasnext()方法返回false,因此您没有获得最后一个元素。
如果你想看到它用于演示目的,请在下面的示例代码中运行 -
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
arrayList.remove(0);
}
}
System.out.println("ArrayList : "+arrayList);
输出 -
----→1
----> 2
ArrayList:[2,3]
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
iterator.remove();
}
}
System.out.println("ArrayList : "+arrayList);
输出 -
----→1
----→2
----→3
ArrayList:[1,3]
答案 1 :(得分:1)
我想你只在第一种情况下遇到问题,因为你试图删除迭代器指向的元素。实际上,第二种情况是成功的,因为您删除了第一个arraylist
元素,此时此元素未被迭代器指向。
(p.s。我同意所有各种和未来的答案,它们将通过展示代码片段来描述如何解决您的问题,我只是向您提供了对发生的事情的解释)
答案 2 :(得分:1)
发生ConcurrentModificationException
是因为您正在删除循环的当前迭代正在读取的相同元素(在索引0处)(值为“1”的那个)。在第二种情况下,您没有看到异常,因为您正在删除索引0处的元素,但正在读取索引1处的元素(值为“2”的元素)。除非您使用支持并发的集合之一,否则在读取元素时不能同时删除元素(请参阅java.util.concurrent
包)
在迭代列表时删除元素(remove(0)
),将“将列表末尾”向左移一。因此,下次检查iterator.hasNext()
时,它将返回false,并且原始的第3个元素永远不会被处理。
答案 3 :(得分:0)
在迭代Collection时,应该使用迭代器删除元素:
iterator.remove()
在第二个代码中,这里:
if (value.equals("2")) {
arrayList.remove(0);
}
删除列表的第一个元素。该列表的大小为2个元素 迭代器实现考虑了列表的大小,以确定它是否具有下一个元素:
public class ArrayList<E> extends AbstractList<E>
...
private class Itr implements Iterator<E> {
public boolean hasNext() {
return cursor != size;
}
}
由于迭代了两个元素并且列表现在的大小为2,因为你删除了它的一个元素,迭代器认为它没有下一个要迭代的元素。
如果使用迭代器删除当前元素,则没有这种副作用。
答案 4 :(得分:0)