wolfd
wolfd

Reputation: 127

Double Iterator Loop

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

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

Upvotes: 4

Views: 14737

Answers (4)

ty1824
ty1824

Reputation: 1200

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

ArrayList does not, however, see javadoc. Nor do most* (perhaps all) of the Java Collections Frameworks List implementations.

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

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

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

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

roads.addAll(temp);

Upvotes: 6

Java Drinker
Java Drinker

Reputation: 3167

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):

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.

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.

Upvotes: 1

Bohemian
Bohemian

Reputation: 425003

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

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

Upvotes: 0

hbhakhra
hbhakhra

Reputation: 4236

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.

Upvotes: 0

Related Questions