0

Java で簡単なタワー ディフェンス ゲームを書いています。これは、スポーン(コンストラクターで設定)から最も近いベースへのパスを見つけるメソッドです。

public int[] findPath(Field startField) {
    ArrayList<TestMonster> monsrs = new ArrayList<TestMonster>();
    TestMonster first = new TestMonster(startField.getCenter(), getStartingDirection(startField), new int[0]);
    monsters.add(first);
    while (true) {
        for (TestMonster monsr : monsrs) {
            monster.move();
            if (getFieldFromCenter(monsr.getPoint()).getState() == 101)
                return monsr.getPath();
            Field field = getFieldFromCenter(monsr.getPoint());
            if (field.isUp())
                monsters.add(new TestMonster(monsr.getPoint(), 0, monster.getPath()));
            if (field.isRight())
                monsters.add(new TestMonster(monsr.getPoint(), 90, monster.getPath()));
            if (field.isDown())
                monsters.add(new TestMonster(monsr.getPoint(), 180, monster.getPath()));
            if (field.isLeft())
                monsters.add(new TestMonster(monsr.getPoint(), 270, monster.getPath()));
            if (monsrs.isEmpty())
                return null;
        }
    }
}

モンスターがベースに到達するために移動した次の方向の配列を返すか、パスがない場合は null を返します。Field クラス オブジェクトであるフィールドを通過します。すべてのフィールドで、モンスターは可能な動きを検索し、設定された方向で新しいモンスターを作成します。新しいモンスターも配列を継承して独自の方向を追加し、それを新しいモンスターに与えます。私の質問は、私のコードのどこに同時 mod ex の可能性があるのですか? どうすればそれを防ぐことができますか?

スタックトレース:

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at towerdefence.MainPanel.findPath(MainPanel.java:160)
at towerdefence.MainPanel$1.actionPerformed(MainPanel.java:62)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1664)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2879)
at javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:306)
at javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:250)
at javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.java:2971)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2963)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2842)
at java.awt.Component.processEvent(Component.java:6282)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
4

3 に答える 3

1

イテレーターはフェイル ファストであるため、イテレーターを使用してコレクションを反復処理している場合、コレクションを同時に変更することはできません。イテレータを使用することを意味し、コレクションの反復と変更を同時に行うことはできません。繰り返しているコレクションに何かを追加または削除するなど。

フェイルファストイテレータとは

この質問も参照してください

于 2013-01-29T09:49:55.150 に答える
0

これを試してください、あなたの問題を解決するかもしれません

List<TestMonster> monsrs = Collections.synchronizedList(new ArrayList<TestMonster>());

ArrayList実装は同期されていません。リストへのアクセスを同期する必要があります。これは、カプセル化オブジェクトを同期するか、Collections.synchronizedListメソッドを使用して実行できます。

詳細はこちらをご確認ください

于 2013-01-29T09:54:01.257 に答える
0

ループ内でオブジェクトを一時リストに追加し、その後 (ループの外で) 元のリストに追加することを検討してください。

反復しているリストを変更することはできません。例:

List<Object> list = new ArrayList<Object>();
list.add("object 1");
list.add("object 2");
for (Object object : list) {
    list.add("another one");
}

java.util.ConcurrentModificationException もスローします。

詳細については、次のドキュメントを参照してください: http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

于 2013-01-29T10:02:40.680 に答える