Search code examples
javaloopsiteratorconcurrentmodification

Invoking a Method on All Elements in an ArrayList Java


I'm trying to call the closeScreen method for all the EntityPlayer objects in the playersUsing array list but I keep running into a ConcurrentModificationException. Iv'e tried every single thing I could think of and its even thrown when I use an iterator. I realize this could possibly be a duplicate but iv'e looked through a ton of questions and none of them have helped me so far. I don't have access to the EntityPlayer class so I can't change any of the code from it. Here's what I'm working with at the moment:

    Iterator<EntityPlayer> iterator = playersUsing.iterator();
    while (iterator.hasNext()) {
        EntityPlayer player = iterator.next();
        player.closeScreen();
        System.out.println("CLOSED: " + player.username);
        iterator.remove();
    }

EDIT: (Here is the closeScreen method):

public void closeScreen()
{
    this.openContainer = this.inventoryContainer;
}

Solution

  • The problem was that I had put the code for removing the players from the list in a pre-existing method that was called indirectly by the closeScreen method.

    The reason why I say indirectly because all the closeScreen method does is update the player's current GUI 'container'. What I didn't realize is that the player is updated in a separate thread and once the player gets updated a GUI change is detected and it calls a 'GuiClose' method for the container. The problem is that this just happens to be where I put the code for removing the players from the list when they are no longer using the GUI. How I fixed this was simply making sure that the player is actually just closing the GUI and that its not my code forcing all the players to exist.

    What really got me was that the closeScreen method is completely ambiguous, all it seems to be doing is changing the players open container variable so I didn't see how that could possibly be immediately closing the players GUI. The behavior that also hid this multi-threaded nature was that the player is updated almost immediately after calling closeScreen and this happens very consistently just after my first iteration to invoke the method on all the players. Which makes it even harder to find because you need multiple players using the GUI, if there's just one player, there will only be one iteration and the code will seem to work fine. Please edit or comment some suggestions for clarification in case I didn't explain this clearly enough.