-3

I am trying to handle the java ConcurrentModificationException exception using try-catch block but still I am getting the same error when compiling the code.

import java.util.*;
public class failFast{
    public static void main(String[] args){
        Map<Integer,String> map = new HashMap<>();
        map.put(100,"Melani");
        map.put(101,"Harshika");
        map.put(102,"Nimna");

        Iterator itr = map.keySet().iterator();

        while(itr.hasNext()){
            System.out.println(itr.next());

            try{
                map.put(103,"Nirmani");
            }
            catch(Exception e){
                System.out.println("Exception is thrown "+e);
            }
            
        }

Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextNode(Unknown Source)
        at java.util.HashMap$KeyIterator.next(Unknown Source)
        at failFast.main(failFast.java:12)
  • 3
    Because it's thrown on this line: `System.out.println(itr.next());`... As clearly shown on the stack trace. – assylias May 26 '21 at 05:02
  • 2
    You don't fix coding bugs with exception handlers. You fix the bugs. The concurrent modification is being performed by *this code.* You must do the add via the iterator, not via the `map` you are iterating. – user207421 May 26 '21 at 05:03
  • @user207421 The general `Iterator` doesn't have an `add` method, only `ListIterator` does. – Andreas May 26 '21 at 05:09
  • To fix, use `ConcurrentHashMap`. – Andreas May 26 '21 at 05:10
  • 1
    @Andreas suggesting `ConcurrentHashMap` is a bad advice as it implies keeping the broken logic. There’s no sense in doing `map.put(103,"Nirmani");` multiple times within a loop. While this is only an example, chances are high that the real life case also should be fixed by changing the program logic rather than resorting to `ConcurrentHashMap`. – Holger May 26 '21 at 08:32

1 Answers1

0

I don't now exactly what you are trying to achive (your code doesn't make much sense for me). Basically you can't change a Map or an other Collection while iterating over it. The only way to change the underlying structure is with the actual Iterator but this is very limited. To catch the ConcurrentModificationException makes not much sense because with your code it will always be thrown, so the catch-block would be your normal code flow, which is really not good.

Possibility 1: Copy keySet to an other collection and iterate over this one

import java.util.*;
public class FailFast{
    public static void main(String[] args){
        Map<Integer,String> map = new HashMap<>();
        map.put(100,"Melani");
        map.put(101,"Harshika");
        map.put(102,"Nimna");

        // Copy keySet to an other collection and iterate over this one
        Iterator itr = new ArrayList(map.keySet()).iterator();
        while(itr.hasNext()){
            System.out.println(itr.next());
            map.put(103,"Nirmani");            
        }

Possibility 2: Collect all the changes and apply them after the loop (this is what I would do)

import java.util.*;
public class FailFast{
    public static void main(String[] args){
        Map<Integer,String> map = new HashMap<>();
        map.put(100,"Melani");
        map.put(101,"Harshika");
        map.put(102,"Nimna");

        Iterator itr = map.keySet().iterator();

        Map<Integer,String> changes = new HashMap<>();
        while(itr.hasNext()){
            System.out.println(itr.next());
            changes.put(103,"Nirmani");            
        }
        map.putAll(changes);
Ogod
  • 878
  • 1
  • 7
  • 15