Search code examples
javaconcurrentmodificationexception

ConcurrentModificationException during putting new element into HashMap


I have some code:

Map<String, Integer> letters = new HashMap<String, Integer>();
letters.put(String.valueOf(input.charAt(0)),
            numberOfLettersInWord(input,input.charAt(0)));
for (int i = 0; i < input.length(); i++) {
   for (String key : letters.keySet()) {
      if (!letters.containsKey(String.valueOf(input.charAt(i)))) {
         letters.put(String.valueOf(input.charAt(i)),
                     numberOfLettersInWord(input,input.charAt(i)));
      } else continue;
      System.out.println(letters);
   }
   System.out.println(1);
}
System.out.println(2);

The main idea in the code - there is some word in String input(not empty, not null, with no non-letter symbols), need to count how many times each letter can be found there. Counting works OK (in the numberOfLettersInWord method) but when I try to add letters and digits to HashMap<String, Integer> some problems happens - it adds all letters and their numbers correctly but some error pops up. For this code it will show:

1
1
{a=4, b=4}
1
1
1
1
{a=4, b=4, c=3}
Exception in thread "main" java.util.ConcurrentModificationException
    at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1579)
    at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1602)
    at LetterCounter.count(LetterCounter.java:25)
    at LetterCounter.main(LetterCounter.java:11)

Process finished with exit code 1

From what I see there is something happens when there are no new letters to be added. Can you explain why this happens and how to solve this?

It supposed to have some more digit outputs after the {a=4, b=4, c=3} was shown but it ends with the exception (it is not really necessary, just an indicator where it stops working...)

The word used in this run was String input = "aabbabcccba";

numberOfLettersInWord returns Integer value of how many times letter input.charAt(i) was found in word input(this works ok)

line 2 in code fragment was used just to make the HashMap contain at least one line (null and empty checks already done by this moment and work well)

I saw people had problems with hashmap.remove() in Why is a ConcurrentModificationException thrown and how to debug it but I am not sure this is the same-same thing that can be solved with that answer. Also I am not sure this answer is applicable for my case ConcurrentModificationException - HashMap


Solution

  • ok, i think i solved it:

    Map<String, Integer> letters = new HashMap<String, Integer>();
    letters.put(String.valueOf(input.charAt(0)),numberOfLettersInWord(input,input.charAt(0)));
    for(int i = 0; i < input.length(); i++) {
       letters.putIfAbsent(String.valueOf(input.charAt(i)),numberOfLettersInWord(input,input.charAt(i)));
    }
    

    i removed some extra code and it started work, even all tests passed