0
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapTest {

      public static void main(String[] args) {

            Map<String, String> hMap = new HashMap<String, String>();
            hMap.put("FIRST", "1");
            hMap.put("SECOND", "2");
            hMap.put("THIRD", "3");
            hMap.put("FOURTH", "4");
            hMap.put("FIFTH", "5");
            hMap.put("SIXTH", "6");
            System.out.println("HashMap before iteration : " + hMap);
            Iterator<String> hashMapIterator = hMap.keySet().iterator();

            while (hashMapIterator.hasNext()) {
                  String key = hashMapIterator.next();
                  if (key.equals("FOURTH")){
                       hMap.put(key + "-SHIVAM", "I AM NEW KEY IN HMAP");
            }
            } 
            System.out.println("HashMap after iteration : " + hMap);
      }
}
Exception in thread "main" java.util.ConcurrentModificationException
  at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
  at java.util.HashMap$KeyIterator.next(Unknown Source)
  at ConcurrentHashMapTest.main(ConcurrentHashMapTest.java:21)

I am wondering why this exception is coming. The exception is not at all seems to be fair in this case.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
user1742919
  • 401
  • 4
  • 11
  • 2
    You're modifying the map while you're iterating through its elements. Also, since you're using a `Map`, you could just use `if hMap.containsKey("FOURTH")) { /* code */ }`. – Luiggi Mendoza Jul 01 '15 at 16:46

2 Answers2

4

You are not allowed to modify a collection or map while iterating over it (except for the Iterator.remove() method), because it is unclear how the modification should affect the iteration. Instead store the keys and values to add in a separate map and then use putAll after the loop.


Example 1: putting entries

Map<String, String> map = /* ... */;
Map<String, String> mapToPut = new HashMap<>();
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
  String key = iterator.next();
  if (key.equals("Test")) {
    mapToPut.put("New key for " + key, "new value");
  }
}
map.putAll(mapToPut);

Example 2: removing entries

Map<String, String> map = /* ... */;
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
  String key = iterator.next();
  if (key.equals("Test")) {
    iterator.remove();
  }
}
Robin Krahl
  • 5,268
  • 19
  • 32
  • agree!!! but is it in docs??? – user1742919 Jul 01 '15 at 16:46
  • 1
    Yes. For [`HashMap`](http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html), the class documentation says: *… if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a 'ConcurrentModificationException'.‘ – Robin Krahl Jul 01 '15 at 16:48
  • 4
    Minor correction, you actually *can* modify the collection while iterating it - but you have to use the iterator to do the modification - for example, if the iterator supports `remove()` - you can remove elements while iterating. ConcurrentModificationException happens only when you try to modify the collection NOT with the iterator you're using to iterate it. – Nir Alfasi Jul 01 '15 at 16:49
  • @alfasin Thanks, you’re right. – Robin Krahl Jul 01 '15 at 16:50
  • can i get piece of code for above stmt..if possible – user1742919 Jul 01 '15 at 16:51
  • I added examples for both putting and removing entries. – Robin Krahl Jul 01 '15 at 16:55
  • http://stackoverflow.com/questions/223918/iterating-through-a-list-avoiding-concurrentmodificationexception-when-removing the ans which has 20 likes ...if you go through that..then its says even in remove we get exception..is nt it?? – user1742919 Jul 01 '15 at 16:58
  • This only applies to `HashMap.remove`, not to `Iterator.remove`. – Robin Krahl Jul 01 '15 at 17:00
1

ConcurrentModificationException is because you are modifying the collection while iterating it.

You can change the logic something as below to avoid it

   Map<String, String> hMap = new HashMap<String, String>();
                            hMap.put("FIRST", "1");
                            hMap.put("SECOND", "2");
                            hMap.put("THIRD", "3");
                            hMap.put("FOURTH", "4");
                            hMap.put("FIFTH", "5");
                            hMap.put("SIXTH", "6");
                            System.out.println("HashMap before iteration : " + hMap);
                            Iterator<String> hashMapIterator = hMap.keySet().iterator();
                            boolean isFourth =false;
                            while (hashMapIterator.hasNext()) {
                                  String key = hashMapIterator.next();
                                  if (key.equals("FOURTH")){
                                      isFourth=true; 

                            }
                            } 
                            if(isFourth)
                            hMap.put("FOURTH" + "-SHIVAM", "I AM NEW KEY IN HMAP");
                            System.out.println("HashMap after iteration : " + hMap);
KDP
  • 1,481
  • 7
  • 13