java 双迭代器循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7017067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 18:17:43  来源:igfitidea点击:

Double Iterator Loop

javalistiteratorlinked-list

提问by wolfd

So I have this loop in my code that needs two separately working Iterators. However, when it tries to use rbIterator.next(), java throws a ConcurrentModificationException. How do I stop that from happening? Thanks

所以我的代码中有这个循环需要两个单独工作的迭代器。但是,当它尝试使用 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);
    }
}

回答by ty1824

You can't add items to most standard implementations of Listwhile iterating over them, unless you create an implementation that allows it!

您不能List在迭代时将项目添加到大多数标准实现中,除非您创建一个允许它的实现!

ArrayListdoes not, however, see javadoc. Nor do most* (perhaps all) of the Java Collections Frameworks Listimplementations.

ArrayList但是,没有看到javadoc。大多数*(也许全部)Java Collections FrameworksList实现也没有。

A solution would be to create a new list, temp, before iterating, add elements to tempwhile you iterate, and then add all of the elements in tempto the first.

一个解决方案是创建一个新列表,temp在迭代之前,在迭代时添加元素temp,然后将所有元素添加temp到第一个。

Edit: used addAll(temp), thanks @Michael Easter

编辑:使用过addAll(temp),谢谢@Michael Easter

List<Road> temp = new ArrayList<Road>();

for(Road ra : roads){
    for (Road rb : roads){
        temp.add(xyz);
    }
}

roads.addAll(temp);

回答by Java Drinker

If you use a ListIterator<E>instead, you will be able to add. The reason you are getting the exception is b/c of this(from the javadocs):

如果您使用 aListIterator<E>代替,您将能够添加。你得到异常的原因是这个(来自javadocs)的b/c:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间对列表进行结构修改,除了通过迭代器自己的 remove 或 add 方法外,迭代器将抛出 ConcurrentModificationException。

You cannot modify the list itself directly, but through the iterator, you may. The base Iterator<E>class does not have an add method, but ListIterator<E>does, which is what you are getting when you call the obj.listIterator()anywqay.

您不能直接修改列表本身,但可以通过迭代器。基Iterator<E>类没有 add 方法,但ListIterator<E>有,这就是调用obj.listIterator()anywqay时得到的。

回答by hbhakhra

I have experienced this problem before. It is because you are trying to iterate over the same thing (roads) twice. This is dangerous, because if one iterator modifies roads, then the other iterator is thrown into an unknown/unreliable state.

我以前遇到过这个问题。这是因为您试图对同一事物(道路)进行两次迭代。这是危险的,因为如果一个迭代器修改了道路,那么另一个迭代器就会陷入未知/不可靠的状态。

If you could manage to use a for loop that would solve this problem, since it seems to fulfil the needs. That would depend on the type of roads (which you have not included) though.

如果您可以设法使用可以解决此问题的 for 循环,因为它似乎满足了需求。不过,这取决于道路的类型(您未包括在内)。

回答by Bohemian

You can't using an Iterator. However, you can use direct access via List's get()method.

你不能使用迭代器。但是,您可以通过 List 的get()方法使用直接访问。

This code does what you want (and compiles and runs OK):

此代码执行您想要的操作(并且编译和运行正常):

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);
    }
}