4

I'm writing a program as part of tutorial for a beginner Java student. I have the following method and whenever I run it, it gives me the following exception:

  java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at Warehouse.receive(Warehouse.java:48)
        at MainClass.main(MainClass.java:13)

Here's the method itself, within the class Warehouse:

public void receive(MusicMedia product, int quantity) {

  if ( myCatalog.size() != 0) { // Checks if the catalog is empty

    // if the catalog is NOT empty, it will run through looking to find
    // similar products and add the new product if there are none
    for (MusicMedia m : myCatalog) { 
        if ( !m.getSKU().equals(product.getSKU()) ) {
                myCatalog.add(product);
        }
    }

  } else { // if the catalog is empty, just add the product
        myCatalog.add(product);
  }
}

The problem seems to be with the if else statement. If I don't include the if else, then the program will run, although it won't work properly because the loop won't iterate through an empty ArrayList.

I've tried adding a product just to keep it from being empty in other parts of the code, but it still gives me the same error. Any ideas?

javanna
  • 59,145
  • 14
  • 144
  • 125
user1104775
  • 259
  • 1
  • 3
  • 7

2 Answers2

6

You can't be iterating through the same list you're going to add things to. Keep a separate list of the things you're going to add, then add them all at the end.

Kylar
  • 8,876
  • 8
  • 41
  • 75
  • So it doesn't matter that the iteration and the adding aren't happening at the same time? (separated by the if else) – user1104775 Dec 18 '11 at 18:20
  • You can't modify a collection while you're iterating over it. That is the cause of **any** `ConcurrentModificationException` in Java. – Nathan Moos Dec 18 '11 at 18:20
  • @user1104775 it does not matter. You cannot modify a collection inside an iteration loop. – Nathan Moos Dec 18 '11 at 18:21
  • I seemed to be focusing too much on the second add I forgot about the first one within the loop. Thanks! – user1104775 Dec 18 '11 at 18:27
  • @user1104775 What do you mean, not iterating and adding at the same time? Everything that happens between for (...) { and the closing } has the open iterator created using MusicMedia m : myCatalog in scope. It's the myCatalog.add(...) in the if (!m.getSku()...) which is a concurrent modification. - ah you noticed so yourself :) – extraneon Dec 18 '11 at 18:27
4

You must not modify mCatalog while you're iterating over it. You're adding an element to it in this loop:

for (MusicMedia m : myCatalog) { 
    if ( !m.getSKU().equals(product.getSKU()) ) {
            myCatalog.add(product);
    }
}

See ConcurrentModificationException and modCount in AbstractList.

Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92