Ошибка программирования Java: java.util.ConcurrentModificationException

Я пишу программу как часть учебника для начинающего студента Java. У меня есть следующий метод, и всякий раз, когда я его запускаю, он дает мне следующее исключение:

  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)

Вот сам метод внутри класса 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);
  }
}

Проблема, похоже, связана с оператором if else. Если я не включу if else, программа запустится, хотя и не будет работать должным образом, потому что цикл не будет выполнять итерацию по пустому ArrayList.

Я пытался добавить продукт только для того, чтобы он не был пустым в других частях кода, но все равно выдает ту же ошибку. Любые идеи?


person user1104775    schedule 18.12.2011    source источник


Ответы (2)


Вы не должны изменять mCatalog во время его повторения. Вы добавляете к нему элемент в этом цикле:

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

См. ConcurrentModificationException и modCount в AbstractList.

person Adam Zalcman    schedule 18.12.2011
comment
Большое спасибо, слишком долго глядя на код, казалось, я забыл об этой части. - person user1104775; 18.12.2011

Вы не можете перебирать один и тот же список, в который собираетесь что-то добавлять. Составьте отдельный список вещей, которые вы собираетесь добавить, а затем добавьте их все в конце.

person Kylar    schedule 18.12.2011
comment
Значит, не имеет значения, что итерация и добавление происходят не одновременно? (разделенные if else) - person user1104775; 18.12.2011
comment
Вы не можете изменить коллекцию во время ее повторения. Это причина любого ConcurrentModificationException в Java. - person Nathan Moos; 18.12.2011
comment
@ user1104775 не имеет значения. Вы не можете изменить коллекцию внутри цикла итераций. - person Nathan Moos; 18.12.2011
comment
Кажется, я слишком много внимания уделял второму добавлению, я забыл о первом в цикле. Спасибо! - person user1104775; 18.12.2011
comment
@user1104775 user1104775 Что вы имеете в виду, не повторяя и не добавляя одновременно? Все, что происходит между for (...) { и close }, имеет открытый итератор, созданный с помощью MusicMedia m : myCatalog в области видимости. Это myCatalog.add(...) в if (!m.getSku()...), который является параллельной модификацией. - а вы сами это заметили :) - person extraneon; 18.12.2011