我目前正在使用Java编写多人游戏。我当前的代码(即获得错误)就是这样。
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote){
System.out.println("Socket disconnected.");
for(Game g : Lobby.games){
if(g.hasPlayer(new Player(conn))){
Player ourPlayer = null;
for(Player p : g.getPlayers()){
if(p.getSocket() == conn){
ourPlayer = p;
break;
}
}
if(ourPlayer == null) return;
g.removePlayer(ourPlayer);
for(Player p : g.getPlayers()){
send(p.getSocket(), Messages.SEND_REMOVE_PLAYER + ourPlayer.getName());
}
if(g.getPlayers().size() == 0){
Lobby.removeGame(g);
}
}
}
}
现在请不要询问onClose等功能。这不会导致问题。
我收到以下行的ConcurrentModificationException:
for(Game g : Lobby.games){
Lobby.games是" Game"的空数组列表。在Lobby.java里面。通过其他功能添加游戏。
public static ArrayList<Game> games = new ArrayList<Game>();
更新:这是removeGame:
public static void removeGame(Game game){
Iterator<Game> itr = games.iterator();
while(itr.hasNext()){
Game g = itr.next();
if(g.getId() == game.getId()){
System.out.println("Game "+g.getId()+" removed");
itr.remove();
}
}
}
抱歉模糊不清。如果您需要更多代码,我一定会添加它。谢谢!
答案 0 :(得分:2)
你的问题(几乎可以肯定)在这里:
for(Game g : Lobby.games) {
// other code
if (g.getPlayers().size() == 0){
Lobby.removeGame(g);
}
}
如果Lobby.removeGame(g)
更改Lobby.games
的内容,那么您将在迭代时修改Lobby.games
(foreach
循环隐式迭代Lobby.games
)
使用迭代器并调用Iterator.remove()
,或者在循环后保存要删除的游戏集合,或者重新组织代码以避免这种情况。
答案 1 :(得分:0)
您的Lobby.removeGame(g)
调用意味着您打算修改列表,尽管您现在正在迭代它,这将完全使隐式排序无效。
如果您需要这样做,请使用明确的反向循环,以便您只修改列表中不会影响您尚未获得的部分顺序的部分:
for(int i=Lobby.games.size()-1; i>-1; i--) {
Game g = Lobby.games.get(i);
// this is now safe, because you're only ever going to see
// indices lower than the current "i", and the removal
// only how long Lobby.games is *after* "i", not before it.
Lobby.games.remove(g)
}