1

你好。ConcurrentModificationException小型遊戲

我正在運行一個服務器並添加了一個minigame。

每當遊戲即將開始時,它首先調用onStart()。現在,我得到ConcurrentModificationException的在這條線:

for(Player p : waiting) { 

這裏是方法:

public void onStart() { 
    trawler.players.clear(); 
    for(Player p : waiting) { 
     if(!boat.playerInArea(p)) { 
      waiting.remove(p); 
     } 
    } 

    for(Player p : waiting) { 
     trawler.players.add(p); 
    } 

    trawler.start(); 
    waiting.clear(); 
} 

,如果你需要的類,在這裏,他們是:

TrawlerWaitingRoom。 java:

package server.model.minigames.trawler; 

import server.model.players.Location; 
import server.model.players.Player; 

public class TrawlerWaitingRoom extends WaitingRoom { 
private Trawler trawler; 
//private Location boat = new Location(2668,2674,3165,3185); 
private Location boat = new Location(2808, 2811,3415,3425); 


public TrawlerWaitingRoom(Trawler trawler) { 
    super(1, 2); 
    this.trawler = trawler; 
} 

@Override 
public boolean startGame() { 
    if(trawler.inProgress()) { 
     return false; 
    } 
    return true; 
} 

@Override 
public void onStart() { 
    trawler.players.clear(); 
    for(Player p : waiting) { 
     if(!boat.playerInArea(p)) { 
      waiting.remove(p); 
     } 
    } 

    for(Player p : waiting) { 
     trawler.players.add(p); 
    } 

    trawler.start(); 
    waiting.clear(); 
} 

@Override 
public void onLeave(Player p) { 
    p.asClient().getPA().movePlayer(2804, 3421, 0); 
    //p.asClient().getPA().movePlayer(2676, 3170, 0); 
} 

@Override 
public void onJoin(Player p) { 
    p.asClient().getPA().movePlayer(2808, 3421, 1); 
    //p.asClient().getPA().movePlayer(2672, 3170, 1); 
    if(!isActive()) { 
     p.asClient().sendMessage(trawler.getGameTime() == 0 ? "The trawler will be returning in less than a minute!" : "The trawler will return in "+trawler.getGameTime() + (trawler.getGameTime() == 1 ? " minute" : " minutes")+"!"); 
    } else { 
     p.asClient().sendMessage(getTimeRemaining() == 0 ? "The trawler will be leaving in less than a minute!" : "The trawler will leave in "+ getTimeRemaining() + (getTimeRemaining() == 1 ? " minute" : " minutes")+"!"); 
    } 
} 

@Override 
public Location getLocation() { 
    return boat; 
} 

@Override 
public void onTimeChange() { 
    for(Player p : waiting) { 
     if(!isActive()) { 
      p.asClient().sendMessage(trawler.getGameTime() == 0 ? "The trawler will be returning in less than a minute!" : "The trawler will return in "+trawler.getGameTime() + (trawler.getGameTime() == 1 ? " minute" : " minutes")+"!"); 
     } else { 
      p.asClient().sendMessage(getTimeRemaining() == 0 ? "The trawler will be leaving in less than a minute!" : "The trawler will leave in "+ getTimeRemaining() + (getTimeRemaining() == 1 ? " minute" : " minutes")+"!"); 
     } 
    } 
} 

@Override 
public boolean canStart() { 
    if(trawler.inProgress()) { 
     return false; 
    } 
    if(waiting.size() < minimumPlayers) { 
     return false; 
    } 
    return true; 
} 

}

GroupMinigame.java:

package server.model.minigames.trawler; 

import server.model.minigames.trawler.WaitingRoom; 

public abstract class GroupMinigame { 

public abstract WaitingRoom getWaitingRoom(); 

public abstract String getWaitingRoomMessage(); 
} 

WaitingRoom.java: http://pastebin.com/KkC8ReWV

Trawler.java: http://pastebin.com/XW5XrsjR

在此先感謝!

回答

6

這裏的問題:

for(Player p : waiting) { 
    if(!boat.playerInArea(p)) { 
     waiting.remove(p); // BOOM 
    } 
} 

您不能直接修改你遍歷集合。

相反,你必須使用一個Iterator

for(Iterator<Player> i = waiting.iterator(); i.hasNext();) { 
    Player p = i.next(); 
    if(!boat.playerInArea(p)) { 
     i.remove(); // Allowed with an iterator 
    } 
} 
+0

測試你的代碼! – user2598506

+0

現在,這解決了我的問題,但它不會將我添加到trawler.players列表中。 \t \t爲(玩家P:等待){ \t \t \t trawler.players.add(P); \t \t} – user2598506

0

你創建一個對象上的迭代器,通過使用for-each循環。然後嘗試編輯它,這在Java中是不允許的。

for(Player p : waiting) { 
    // Iterator created. 
    if(!boat.playerInArea(p)) { 
     // Change to iterated object. 
     waiting.remove(p); 
    } 
} 

你的選擇是創建一個新的列表,並覆蓋舊名單。例如:

private List<Waiting> newWaiting = new ArrayList<Waiting>(); 

for(Player p : waiting) { 
    // Iterator created on the WAITING object. 
    if(boat.playerInArea(p)) { 
     newWaiting.add(p); 
     // Logic is flipped, so those that pass are carried forward. 
    } 
} 
waiting = newWaiting; 
// Set waiting's reference to point to newWaiting's reference. 
0

使用Iterator#remove()List同時通過List迭代刪除元素。

Iterator<Player> itr = waiting.iterator(); 
while(itr.hasNext()) { 
    Player p = itr.next(); 
    if(!boat.playerInArea(p)) { 
     itr.remove(); 
    } 
} 
0

這很簡單:當您將其作爲循環使用時,您將從列表waiting中刪除對象。這是不允許的。 而是嘗試以下操作:

List<Player> temporaryList = new LinkedList<Player>(waiting); 
for(Player p : temporaryList) { 
    if(!boat.playerInArea(p)) { 
     waiting.remove(p); 
    } 
}