-1

I am facing java.util.ConcurrentModificationException while adding items to an existing list corresponding to a key

Here is my code

final Map<String, List<Apple>> feedToApplesMap = new HashMap<>();
for (final Apple Apple : AppleList) {
    final List<String> feedDocumentIds = Apple.getFeedDocumentIds();
    for (final String feedId : feedDocumentIds) {
        final List<Apple> AppleListForFeed = feedToApplesMap
                .getOrDefault(feedId, new ArrayList<>());
        AppleList.add(Apple);
        feedToApplesMap.put(feedId, AppleListForFeed);
    }
}

I am unable to use iterator to solve this ? Any suggestions ?

geocodezip
  • 158,664
  • 13
  • 220
  • 245
Prakhar
  • 530
  • 10
  • 24
  • why would you want to do `AppleList.add(Apple);`? – Naman Oct 16 '20 at 05:46
  • Please edit your question to include the full stack trace of the Exception. – tgdavies Oct 16 '20 at 05:46
  • A more Java 8-suited approach would be to use a `Stream` and `groupingBy()`. By doing this, you would likely get rid of all the nested loops and limit the possibility for bugs (such as the `add()` to the wrong list in your code). – Magnilex Oct 16 '20 at 07:28
  • 1
    Adhere to the naming conventions. This code is really hard to read. – Holger Oct 16 '20 at 08:08
  • 1
    Apparently, you want to add to `AppleListForFeed` instead of `AppleList`. In that case, simplify the entire loop body to `feedToApplesMap .computeIfAbsent(feedId, key -> new ArrayList<>() ) .add(Apple);`, so you don’t need another `put` operation. – Holger Oct 16 '20 at 08:46

3 Answers3

1

It seems like you're storing apples in a wrong place. Shouldn't it be

AppleListForFeed.add(Apple) instead of AppleList.add(Apple) ?

andbi
  • 4,426
  • 5
  • 45
  • 70
1

I agree with @andbi that the question is due to a typo. But just for the exception, By doing so for (final Apple Apple : AppleList) you are still using Iterator unintentionally, that's why here AppleList.add(Apple); will throw ConcurrentModificationException, you can do it like this to avoid using Iterator:

final Map<String, List<Apple>> feedToApplesMap = new HashMap<>();
int size = AppleList.size();
for (int i = 0; i < size; i++) {
    final Apple Apple = AppList.get(i);
    final List<String> feedDocumentIds = Apple.getFeedDocumentIds();
    for (final String feedId : feedDocumentIds) {
        final List<Apple> AppleListForFeed = feedToApplesMap
                .getOrDefault(feedId, new ArrayList<>());
        AppleList.add(Apple);
        feedToApplesMap.put(feedId, AppleListForFeed);
    }
}

Please be aware that enhanced for-loop is just a syntatic sugar for for-loop with Iterator, the following two are the same:

    for (Iterator<T> i = c.iterator(); i.hasNext(); )
 
    for (T t : c)
    

Here is the document: The For-Each Loop

Qiu Zhou
  • 1,235
  • 8
  • 12
0

This happens when we are iterating a list using for loop or for each and some elements are added in between during iterating so use iterator or iterating a list:

val iterator = yourList.iterator()
    while (iterator.hasNext()) {
        val currentItem = iterator.next()
    }

now add or delete any other element in your list during iterating.

DeePanShu
  • 1,236
  • 10
  • 23