Двойной Итератор - PullRequest
       13

Двойной Итератор

3 голосов
/ 11 августа 2011

Итак, в моем коде есть этот цикл, для которого нужны два отдельно работающих итератора. Однако, когда он пытается использовать 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);
    }
}

Ответы [ 4 ]

6 голосов
/ 11 августа 2011

Вы не можете добавлять элементы в большинство стандартных реализаций 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);
1 голос
/ 11 августа 2011

Если вместо этого вы используете ListIterator<E>, вы сможете добавить. Причина, по которой вы получаете исключение, заключается в том, что это б / к (из javadocs):

Итераторы, возвращаемые итераторами этого класса и listIterator методы работают быстро: если список структурно изменен время после создания итератора, любым способом, кроме как через собственные методы удаления или добавления итератора, итератор выдаст ConcurrentModificationException.

Вы не можете изменить сам список напрямую, но через итератор вы можете. Базовый класс Iterator<E> не имеет метода добавления, но ListIterator<E> имеет, что вы и получаете, когда вызываете obj.listIterator() anywqay.

0 голосов
/ 11 августа 2011

Вы не можете использовать итератор.Однако вы можете использовать прямой доступ через метод 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);
    }
}
0 голосов
/ 11 августа 2011

Я уже сталкивался с этой проблемой раньше.Это потому, что вы пытаетесь перебрать одно и то же (дороги) дважды.Это опасно, потому что если один итератор изменяет дороги, то другой итератор переходит в неизвестное / ненадежное состояние.

Если вам удастся использовать цикл for, который решит эту проблему, поскольку он, кажется, удовлетворяет потребности.Это будет зависеть от типа дорог (которые вы не включили), хотя.

...