I have this little piece of code and it gives me the concurrent modification exception. I cannot understand why I keep getting it, even though I do not see any concurrent mo
I cannot understand why I keep getting it, even though I do not see any concurrent modifications being carried out.
Between creating the iterator and starting to use the iterator, you added arguments to the list that is to be iterated. This is a concurrent modification.
ListIterator<String> it = s.listIterator();
for (String a : args)
s.add(a); // concurrent modification here
if (it.hasNext())
String item = it.next(); // exception thrown here
Create the iterator AFTER you've finished adding elements to the list:
for (String a : args)
s.add(a);
ListIterator<String> it = s.listIterator();
if (it.hasNext())
String item = it.next();
If the above solutions doesn't work properly. You can use old for-loop for iterating a List at the same time adding new items. See the example below:
import java.util.*;
public class SomeClass {
public static void main(String[] args) {
ArrayList<AClass> aList = new ArrayList<AClass>(); // we will iterate this
// this will cause ConcurrentModificationException.
// Since we are iterating the list, at the same time modifying it.
/*for(AClass a: aList){
aList.add(someMethod(a));
}*/
// old fashion for-loop will help
int limit = aList.size();
for(int i=0; ctr<limit; ++i){
AClass a = aList.get(i);
aList.add(someMethod(a));
}
}
}
to understand this lets look at source of HashMap implementation:
public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable{
which contains HashIterator as below:
private abstract class HashIterator {
...
int expectedModCount = modCount;
...
HashMapEntry<K, V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
....
}
every time you create a iterator:
to avoid this u can:
this will allow you to iterate and add or remove elements at the same time without rising an exception
Concurrency map/list iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.
More info on CopyOnWriteArrayList
This didn't work:
LinkedList<String> linkedList = new LinkedList<String>();
ListIterator listIterator = linkedList.listIterator();
linkedList.add("aa");
linkedList.add("bb");
This worked:
LinkedList<String> linkedList = new LinkedList<String>();
linkedList.add("aa");
linkedList.add("bb");
ListIterator listIterator = linkedList.listIterator();
You are not allowed to continue iterating over an iterator after the underlying list is modified. Here you create the iterator before adding a few items to s
, and then proceed to do a hasNext()
and a next()
on it after the additions, leading to the ConcurrentModificationException
To avoid the ConcurrentModificationException
, you should write your code like this:
import java.util.*;
public class SomeClass {
public static void main(String[] args) {
List<String> s = new ArrayList<String>();
for(String a : args)
s.add(a);
ListIterator<String> it = s.listIterator();
if(it.hasNext()) {
String item = it.next();
}
System.out.println(s);
}
}
A java.util.ListIterator
allows you to modify a list during iteration, but not between creating it and using it.