Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I getting java.util.ConcurrentModificationException?

Tags:

java

exception

As I run the following code :

    import java.util.LinkedList;

    class Tester {
      public static void main(String args[]) {
        LinkedList<String> list = new LinkedList<String>();
        list.add(new String("suhail"));
        list.add(new String("gupta"));
        list.add(new String("ghazal"));
        list.add(new String("poetry"));
        list.add(new String("music"));
        list.add(new String("art"));

        try {
            for(String s : list) {
            list.add(0,"art");
            list.remove(6);
            System.out.println(list);
        }
        }catch(Exception exc) {
            exc.printStackTrace();
        }

    }
}

I get an exception that says :

java.util.ConcurrentModificationException
    at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
    at java.util.LinkedList$ListItr.next(Unknown Source)
    at Tester.main(Tester.java:14)

Why am I getting this exception ?

Edit : tmpList is a LinkedList whose each node contains an object of type DepConfAttr. I am sorting the tmpList on the basis of memory (Highest memory first), which is one of the attribute of the object of DepConfAttr.

The above code reflected what I am trying to achieve through the following code

int size = tmpList.size();
        int elementBC = 0; // element being checked
        int startIndex = 1;
        for (DepConfAttr dca : tmpList) {
            long maxMem = dca.getMemory(); // Let this be the maximum memory
            for(int i = startIndex ; i < size ; i++) {
                DepConfAttr dcaTmp = tmpList.get(i);
                if(maxMem < dcaTmp.getMemory()) {
                    tmpList.add(elementBC, dcaTmp);
                    tmpList.remove(i+1);
                    maxMem = tmpList.get(elementBC).getMemory();                        
                }
            }
            elementBC++;
            startIndex++;
            size--;
        }
like image 426
Suhail Gupta Avatar asked Aug 26 '13 09:08

Suhail Gupta


3 Answers

Why am I getting this exception ?

You're removing an item from the list other than via the iterator, while iterating over it. You're also adding to the list while you're iterating over it.

It's not really clear what you're trying to achieve here, but other than with the concurrent collections, you'll always get an exception when you try to do that.

One common fix to this is to create a copy of the list first and iterate over that, modifying the original as you go.

like image 82
Jon Skeet Avatar answered Oct 08 '22 23:10

Jon Skeet


When you iterate through a list, you can't remove items from it. Doing so causes the exception.

Do:

int size = list.size();
for (int i = 0 ; i< size ; i++) {
   list.add(0,"art");
   list.remove(6);
   System.out.println(list);
}
like image 2
No Idea For Name Avatar answered Oct 08 '22 23:10

No Idea For Name


The problem is that you're directly modifying the List while an Iterator is trying to run over it. The next time you tell the Iterator to iterate (implicitly, in the for loop), it notices the List has changed out from under it and throws the exception.

Instead, if you need to modify the list while traversing it, grab the Iterator explicitly and use it:

List<String> list = ....
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String s = iterator.next(); // must be called before you can call iterator.remove()
    iterator.remove();
}

You still can't insert into the List while this is going on, and this won't let you remove arbitrary elements, just the current one.

like image 1
chrylis -cautiouslyoptimistic- Avatar answered Oct 08 '22 21:10

chrylis -cautiouslyoptimistic-