Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting ConcurrentException when traversing a list

I am in a very peculiar state. I have a list something like below :-

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");

Now when i do multiple type of traversing, like using advanced for, iterator, and normal for loop, below are the sample code snippets :-

1> Advanced Loop :-

try {
    for(String a : list) {
        System.out.println(a);
        list.add("f");
    }
} catch (Exception e) {
    e.printStackTrace();
}

2> Iterator :-

try {
    Iterator<String> itr =  list.iterator();
    while(itr.hasNext()) {
        System.out.println(itr.next());
        list.add("f");
    }
} catch (Exception e) {
    e.printStackTrace();
}

3> Normal Loop :-

for (int i=0;i<list.size();i++) {
    System.out.println(list.get(i));
    list.add("f");
}

Now, the peculiar problem is, that when using advanced for-loop and iterator, i get the following exception : -

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)


the reason i know, that while iterating through a list, one cannot modify it parallely.

but when i use the normal for loop, then it works properly, Am i missing something??

Please Help!!!..

like image 269
M.J. Avatar asked Dec 27 '22 22:12

M.J.


2 Answers

If you modify a List, it invalidates any Iterator objects created from it. The advanced loop (1) compiles to nearly the same code as the iterator loop (2), meaning that there is an Iterator object created behind the scenes.

The javadocs for ConcurrentMOdificationException have more details.

If you want to add while iterating, use

ListIterator listIter = ...
while(listIter.hasNext())
{
    if(shouldAdd(iter.next())) {
        iter.add(....)
    }
}
like image 153
sbridges Avatar answered Jan 08 '23 19:01

sbridges


The advanced loop is just syntactic sugar for the iterator. The iterator always calls checkForComodification() whenever it runs next(). This method will throw an exception if it sees that you modified the list.

Running the "Normal Loop" does not provide this functionality of checking the modification count because you aren't using an iterator to loop, you are strictly using the for loop construct.

like image 32
Mike Lewis Avatar answered Jan 08 '23 17:01

Mike Lewis