Wednesday 11 June 2014

Addition or removal of element in list while iterating. And java.util.ConcurrentModificationException

One of the favorite topic of  Java interviewers is Collections i.e. java.util package. After series of general and direct questions on collections, they will ask you this question to test your practical knowledge. Question will be in any of the following form :

> How can I add or remove element (object) in list while iterating over it ?
> How to add element in List while iterating in java?
> In Java, can you modify a List while iterating through it?
> Can I add or remove element in list while iterating over it? If yes, how? If no, what will be exception?
> What exception will be thrown when adding or removing element in list while iterating on list, using list's add or remove method ?
> What is concurrent modification exception (java.util.ConcurrentModificationException) ?

Answer to these questions is yes. We can add or remove element (object) in list, but we cannot use list's add() or remove() method. For this purpose, we have to use Iterator's remove() method or ListIterator's add() and remove() method.

####################################################################
//Example of adding element in list using list's add method, it will throw concurrent modification exception

import java.util.*;

public class TestExample {

    public static void main(String[] args) {
   
        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");
        list.add("three");
       
        Iterator<String> itr = list.iterator();
               
        while(itr.hasNext())
        {
            if(itr.next().equals("two"));
                list.add("four");    //will throw java.util.ConcurrentModificationException
        }

    }

}

/*
Output :
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at TestExample.main(TestExample.java:16)

*/
####################################################################

Like in the above example shown, if we use list.add(e) or remove(), then it will throw exception. Because one thread of iterator is already working on list object. If we try to access this list object by any other thread(like add or remove of list's method) at same time, it will be concurrency issue. So it will throw you ConcurrentModificationException.

Best way to add element in list is to use remove() method of Iterator or add() & remove() method of ListIterator. As shown in below example :

####################################################################
 import java.util.*;

public class TestExample {

    public static void main(String[] args) {
  
        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");
        list.add("three");
        System.out.println("Original list content: "+list);
      
        ListIterator<String> itr = list.listIterator();
              
        while(itr.hasNext())
        {
            String s = itr.next();
            if(s.equals("one"))
                itr.remove();
          
            if(s.equals("two"))
                itr.add("four");
        }
        System.out.println("List content after operations:  "+list);
      
    }

}

/ * Output :
Original list content: [one, two, three]
List content after operations:  [two, four, three]
*/
####################################################################

Note :
> Iterator has only remove() method
> ListIterator have both add(e)  and remove() method

2 comments: