Home > database >  ConcurrentModificationException during putting new element into HashMap
ConcurrentModificationException during putting new element into HashMap

Time:02-02

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

CodePudding user response:

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

CodePudding user response:

letters.keySet() is returning a set which is backed by the keys of the HashMap, which you then alter by calling put(). So the conflict here is between the keySet and the keys of the map. You would need to use an iterator, or extract the keys into a separate collection, by copying the keySet each time through the outer loop. Honestly, the algorithm is sounding kind of expensive, though I haven't really tried to work out a better approach...

  • Related