0

I'm working on a plugin for a game server api known as Bukkit; this plugin allows players to play a minigame - a game within their game.

The problem I'm facing is stopping the game. When the game stops, it loops through all players within that game and then removes them. The problem is that when the player is removed, they are removed from the arena list. This arena list is what is being looped over; causing the ConcurrentModificationException.

Here is my code:

ArrayList<String> players = new ArrayList<String>(arena.getPlayers());        
for(String player : players){
    removePlayer(Bukkit.getPlayer(player));
}

Within the removePlayer function, the player is being remove from arena.getPlayers().

Any help would be appreciated.

EDIT: Here's the github repo https://github.com/MCMedia/GunGames/blob/master/src/com/ViralAftermath/GunGame/Arena/ArenaManager.java

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Kondax Design
  • 175
  • 1
  • 1
  • 15

3 Answers3

1

You cannot remove an item from the ArrayList while you uterate over it.

You should change your code to use an Iterator and then call .remove ()

Something like

 Iterator <String> it = players.iterator ();
 while (it.hasNext ()) it.remove ();

It will remove every item from players. But you can use better methods to clear the array.

It will fix your problem, of course you should adapt this example to your real code. But the problem is caused when you remove an item from an ArrayList whioe you are reading it. You should use the appropriate .remove item or use an index..

Marco Acierno
  • 14,682
  • 8
  • 43
  • 53
1

To remove items from ArrayList while iterating it, you have to use Iterator.remove(). Change the code to

  ArrayList<String> players = new ArrayList<String>(arena.getPlayers());         
  Iterator playersIterator =  players.iterator();
    while(playersIterator.hasNext()){
        playersIterator.remove();
    }

This will not throw ConcurrentModificationException. Hope this helps!

Documentation states that when a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.This happens in your case.

Keerthivasan
  • 12,760
  • 2
  • 32
  • 53
0

Thanks for the answers.. fixed it like this:

             int place = 0;
             ArrayList<String> players = new ArrayList<String>(arena.getPlayers());         
             Iterator<String> playersIterator =  players.iterator();
             while(playersIterator.hasNext()){
                 place ++;
                 Player player = Bukkit.getPlayer(playersIterator.next());
                 player.getInventory().setArmorContents(null);
                 player.getInventory().clear();
                 player.setHealth(player.getMaxHealth());
                 player.setFireTicks(0);
                 player.teleport(arena.getLobby());
                 arena.sendMessage(ChatColor.BLUE + player.getName() + " has left the Arena! There are " + arena.getPlayers().size() + " players currently left!");
                 player.getInventory().setContents(inv.get(player.getName()));
                 player.getInventory().setArmorContents(armour.get(player.getName()));
                 Bukkit.broadcastMessage(arena.getPlayers().toString());
                 playersIterator.remove();
                 if(place == arena.getPlayers().size()){
                     arena.getPlayers().clear();
                 }
             }
Kondax Design
  • 175
  • 1
  • 1
  • 15