Search code examples
javaarraysloopsconcurrentmodification

Concurrent Modification exception when i compile my code,


I've been given this exercise to do and I'm struggling to understand why I keep getting concurrent modification error when I compile my code.

"If the list contains a film with a title that matches the parameter title then update it's length and genre. If no match is found create a new film and add it to the list."

I've managed to check if there's a match for title however when there isn't one I'm unable to successfully add a new film to my array. Here's the code I wrote:

public void updateLengthAndGenre(String title, int length, String genre) {
    ArrayList<Film> output = new ArrayList<>();
    boolean found = false;

    for (Film film : films) {
        if (film.getTitle().equals(title)) {
            found = true;
            film.setGenre(genre);
            film.setLength(length);
        }
    }

    for (Film film : films) {
        if (!found) {
            films.add(new Film(title, length, genre));
        }
    }
}

Can someone explain why I keep getting this error and also give me some advice how to remedy it?


Solution

  • The reason you're getting this exceotion is because you're trying to simultaneously add to a collection while iterating over it. You cannot do this. In your case, it doesn't seem like you actually even have to do this at all.

    public void updateLengthAndGenre(String title, int length, String genre) {
        ArrayList<Film> output = new ArrayList<>();
    
        for (Film film : films) {
          if (film.getTitle().equals(title)) {
              film.setGenre(genre);
              film.setLength(length);
              return;
          }
        }
    
        films.add(new Film(title, length, genre));  // synchronize if you're multithreading
    }
    

    This has the same effect. If you absolutely need to add to a collection while iterating, you can use a java.util.ListIterator.

    ListIterator<Film> filmIter = films.listIterator();
    while(filmIter.hasNext()){
        if( /* some condition */){
            fillmIter.add(new Film(title, length, genre));
        }
        filmIter.next(); // example only.
    }