我的代码中有这个循环,它需要两个单独工作的迭代器。然而,当它尝试使用rbIterator.next()时,java抛出ConcurrentModificationException。我该如何阻止这种情况的发生?由于
Iterator<Road> raIterator = roads.listIterator(0); //I also tried .iterator(), with no avail
while(raIterator.hasNext()){
Road ra = raIterator.next();
Iterator<Road> rbIterator = roads.listIterator(0);
while(rbIterator.hasNext()){
Road rb = rbIterator.next();
//snipped code that adds a road to the list
roads.add(xyz);
}
}
您不能在迭代List
的大多数标准实现中添加项,除非您创建一个允许这样做的实现!
ArrayList
没有看到javadoc。大多数(也许是全部)Java Collections Frameworks的List
实现也没有。
一种解决方案是在迭代之前创建一个新的列表temp
,在迭代时向temp
添加元素,然后将temp
中的所有元素添加到第一个列表中。
编辑:使用addAll(temp)
,谢谢@Michael Easter
List<Road> temp = new ArrayList<Road>();
for(Road ra : roads){
for (Road rb : roads){
temp.add(xyz);
}
}
roads.addAll(temp);
如果您使用ListIterator<E>
代替,您将能够添加。您获得异常的原因是b/c(来自javadocs):
由该类的迭代器和listtiterator返回的迭代器方法是快速故障的:如果在任何地方对列表进行了结构修改创建迭代器后的时间,除了通过迭代器自己的remove或add方法,迭代器将抛出ConcurrentModificationException。
不能直接修改列表本身,但可以通过迭代器修改。基本的Iterator<E>
类没有add方法,但是ListIterator<E>
有,这就是您调用obj.listIterator()
时所得到的。
我以前遇到过这个问题。这是因为你试图对相同的东西(道路)进行两次迭代。这很危险,因为如果一个迭代器修改了道路,那么另一个迭代器就会陷入未知/不可靠的状态。
如果你能设法使用for循环来解决这个问题,因为它似乎满足了需求。这将取决于道路的类型(你没有包括)。
不能使用Iterator。但是,您可以通过List的get()方法使用直接访问。
这段代码做了你想要的(并且编译和运行正常):
for (int i = 0; i < roads.size(); i++) {
Road ra = roads.get(i);
for (int j = 0; j < roads.size(); j++) {
Road rb = roads.get(i);
//snipped code that adds a road to the list
roads.add(xyz);
}
}