1

For the Below java program with Hash Map, ConcurrentModification Exception thrown, i had marked the lines where the Exception is thrown in the Program.

I had skipped the login of Insertion of Data into the HashMap for now

import java.util.ArrayList;
 import java.util.HashMap;

 public class MainClass {

     public static void main(String[] args) {

         ArrayList<HashMap<String, ArrayList<String>>> arrMain = new ArrayList<HashMap<String, ArrayList<String>>>();

         HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();

         ArrayList<String> strings = new ArrayList<String>();

         // Code to build the above Maps with all required Data, Skipped for Now

         //******************Scenario 1****************
         for (HashMap<String, ArrayList<String>> dataMap : arrMain) { //ConcurrentModification Exception
             for (String s : dataMap.get("Key")) {
                 ArrayList<String> newStrings = new ArrayList<String>();
                 newStrings.addAll(dataMap.get("Key")); 
                 newStrings.add("New String");
                 dataMap.put("Key", newStrings);
             }

         }

         //******************Scenario 2****************
         for (HashMap<String, ArrayList<String>> dataMap : arrMain) {//ConcurrentModification Exception
             for (String s : dataMap.get("Key")) {
                 dataMap.get("Key").add("New String"); 
             }

         }

     }

 }

Error :

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
    at java.util.ArrayList$Itr.next(ArrayList.java:791)
1
  • you can not iterate over hashmap and use addall or add at the same time. it is like to read and change a location at the same time. Commented Oct 21, 2014 at 5:24

3 Answers 3

5

When ever you try to modify the Collection while iterate you will get ConcurrentModificationException. You can try with Iterator to avoid this.

Eg: Iterator with Map

    Map<String, String> map = new HashMap<>();
    map.put("a", "a1");
    map.put("b", "b1");
    map.put("c", "c1");
    System.out.println(map);
    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry) it.next();
        System.out.println(pairs.getKey() + " = " + pairs.getValue());
        it.remove(); // no a ConcurrentModificationException
    }
    System.out.println(map);

Out put:

{b=b1, c=c1, a=a1}
b = b1
c = c1
a = a1
{}
Sign up to request clarification or add additional context in comments.

Comments

4

You have marked 2 ConcurrentModificationException points in your code but only one is reproducible and reasonable.

The 2nd one:

for (HashMap<String, ArrayList<String>> dataMap : arrMain) {
     for (String s : dataMap.get("Key")) { // HERE 
         dataMap.get("Key").add("New String"); 
     }
}

dataMap.get("Key") returns an ArrayList to which inside the for loop you add another element:

dataMap.get("Key").add("New String");

And right after adding an element (modifying it) the for loop would continue. You add an element to the list right in the middle of iterating over it. This causes the ConcurrentModificationException (under the hood the enhanced for uses the iterator of the list to go over its elements, and the iterators next() method throws this exception if the list is modified since the creation of the iterator).

The 1st point in your code where you indicated ConcurrentModificationException, it causes no exception because you iterate over a list and you modify another list, a new list which you create inside the for loop. But I doubt this is what you really want to do.

Comments

0

You can use ConcurrentHashMap

A hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates.

This class obeys the same functional specification as Hashtable, and includes versions of methods corresponding to each method of Hashtable.

However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access.

This class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details.


You can use iterator. iterators are designed to be used by only one thread at a time. They do not throw ConcurrentModificationException.

ConcurrentModificationException

public class ConcurrentModificationException
             extends RuntimeException

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it.

See also

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.