更新Arraylist中的项会抛出ConcurrentModificationException

时间:2016-10-01 09:55:51

标签: java arraylist lwjgl slick

我正在使用lwjgl和slick在java中制作游戏。我有一个世界,其中包含一个arraylist,所有项目都放在地面上,必须更新。但是当它第二次更新项目时会抛出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));

}

2 个答案:

答案 0 :(得分:0)

您正在迭代它时从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对象。

基本上,你必须使用迭代器而不是直接从arraylist中删除。

有关进一步说明,请参阅本网站中的类似问题: Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop

答案 1 :(得分:0)

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

您无法修改for循环中的List。您只能在直接使用Iterator时调用remove方法。