我正在使用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));
}
答案 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方法。