更新 Arraylist 中的项目抛出 ConcurrentModificationException

Updating Items in Arraylist throws ConcurrentModificationException

我正在 java 使用 lwjgl 和 slick 制作游戏。我有一个世界,其中包含一个数组列表,其中所有项目都必须更新。但是,当它第二次更新项目时,它会抛出一个 ConcurrentModificationException。

我该如何解决这个问题?

这是完整的错误:Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at com.jakibah.infinyvale.World.HandleItems(World.java:43) at com.jakibah.infinyvale.World.Update(World.java:65) at com.jakibah.infinyvale.Game.Update(Game.java:29) at com.jakibah.infinyvale.Canvas.CreateCanvas(Canvas.java:41) at com.jakibah.infinyvale.Game.main(Game.java:16)

这是我的代码: 世界:

package com.jakibah.infinyvale;


public class World {

public Tile[][] map;
private int TilesWide, TileHeight;
public ArrayList<Item> items = new ArrayList<Item>();

public World(int volume) {

    this.TilesWide = volume / 2;
    this.TileHeight = volume / 2;
    map = new Tile[TilesWide][TileHeight];
    for (int i = 0; i < map.length; i++) {
        for (int j = 0; j < map[i].length; j++) {
            map[i][j] = new Tile(TileType.Test, i * 32, j * 32, 32);
        }
    }
}

public World(int[][] newMap) {
    this.TilesWide = newMap[0].length;
    this.TileHeight = newMap.length;
    map = new Tile[TilesWide][TileHeight];
    for (int i = 0; i < map.length; i++) {
        for (int j = 0; j < map[i].length; j++) {
            switch (newMap[j][i]) {
            case 0:
                map[i][j] = new Tile(TileType.Test, i * 32, j * 32, 32);
                break;
            }

        }
    }
}

public synchronized void HandleItems() {
    if (!items.isEmpty()) {
        for (Item i : items) {
            i.Update();
        }
    }
}

public Tile GetTile(int xplace, int yplace) {

    if (xplace < TilesWide && yplace < TileHeight && xplace > -1
            && yplace > -1)
        return map[xplace][yplace];
    else
        return null;
}

public void Update() {
    for (int i = 0; i < map.length; i++) {
        for (int j = 0; j < map[i].length; j++) {
            Tile t = map[i][j];
            t.Update();
        }
    }
    HandleItems();
}

项目:

public class Item {
private ItemType type;
private Texture tex;
private int x, y;
private World w;
private int texturefactor;
private int durability;
private int power;

public Item(ItemType type, Texture tex, int x, int y, World w,int texturefactor, int durability, int power) {
    this.type = type;
    this.tex = tex;
    this.x = y;
    this.y = y;
    this.w = w;
    this.texturefactor = texturefactor;
    this.durability = durability;
    this.power = power;
    this.w.getItems().add(this);
}

public void Draw() {
    Canvas.DrawQuadTex(tex, x, y, texturefactor, texturefactor);
}

public void Update() {
    Draw();
    CheckPickUp();
}
public void CheckPickUp(){
    if(Canvas.isColliding(Game.p.getX(), Game.p.getY(), Game.p.getX() + 32, Game.p.getY() - 32, x, y));
    System.out.println("Colliding");
    this.ToBag();
}

public void ToBag() {
    Inventory i = null;
    i = Game.p.getI();
    Game.world.getItems().remove(this);
    i.getInventory().add(new BagItem(type, i, tex, texturefactor, durability, power));

}

您正在从 ArrayList 中删除一个项目,同时迭代它并导致它抛出 ConcurrentModificationException。

让我们跟踪您的代码;

    public synchronized void HandleItems() {
        if (!items.isEmpty()) {
            for (Item i : items) {
                i.Update();
            }
        }
    }

这会调用 Item 对象的 Update(),即:

    public void Update() {
        Draw();
        CheckPickUp();
    }
    public void CheckPickUp(){
        if(Canvas.isColliding(Game.p.getX(), Game.p.getY(), Game.p.getX() + 32, Game.p.getY() - 32, x, y));
        System.out.println("Colliding");
        this.ToBag();
    }

    public void ToBag() {
        Inventory i = null;
        i = Game.p.getI();
        Game.world.getItems().remove(this);
        i.getInventory().add(new BagItem(type, i, tex, texturefactor, durability, power));
    }

关注toBag()。您正在从实际上正在迭代的集合中删除 Item 对象。

基本上,您必须使用迭代器而不是直接从数组列表中删除。

更多解释请参考本站类似问题: Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop

Item.toBag() 导致了此异常。 Game.world.getItems().remove(this); 行试图从 ArrayList 中删除项目。

您不能在 for each 循环中修改列表。直接使用Iterator只能调用remove方法