1

こんにちは。

サーバーを実行していて、ミニゲームを追加しました。

ゲームが始まろうとしているときはいつでも..最初に 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

前もって感謝します!

4

5 に答える 5

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
    }
}
于 2013-07-19T07:55:04.903 に答える
0

このエラーを修正して理解する前に、従わなければならない論理的な手順が 2 つあります。

  1. Javaの「for each」ループはどのように機能しますか? (ヒント: イテレータ)

  2. イテレータを使用すると、どのようにして 同時変更例外が発生する可能性がありますか?

于 2013-07-19T08:01:15.993 に答える
0

を反復処理中にから要素を削除するには、Iterator#remove()を使用します。ListList

Iterator<Player> itr = waiting.iterator();
while(itr.hasNext()) {
    Player p = itr.next(); 
    if(!boat.playerInArea(p)) {
      itr.remove(); 
    }
}
于 2013-07-19T07:56:18.380 に答える
0

waitingそれはかなり単純です:ループとして使用している間、 list からオブジェクトを削除しています。それは許可されていません。代わりに次のことを試してください。

List<Player> temporaryList = new LinkedList<Player>(waiting);
for(Player p : temporaryList ) {
    if(!boat.playerInArea(p)) {
        waiting.remove(p);
    }
}
于 2013-07-19T07:57:06.447 に答える
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. 
于 2013-07-19T07:55:48.393 に答える