2016-10-01 5 views
-2

Ich mache ein Spiel in Java mit Lwjgl und Slick. Und ich habe eine Welt, die eine Arraylist enthält, in der alle Gegenstände auf dem Boden liegen, die aktualisiert werden müssen. Wenn die Objekte jedoch ein zweites Mal aktualisiert werden, wird eine ConcurrentModificationException ausgelöst.Aktualisieren von Elementen in Arraylist Würfe ConcurrentModificationException

Wie kann ich das beheben?

Dies ist der vollständige Fehler: 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)

Und dies ist mein Code: Welt:

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(); 
} 

Item:

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

Fügen Sie Ihren Code hier in Textform mit der richtigen Formatierung ein. Veröffentlichen Sie keine Links zu externen Quellen. – progyammer

Antwort

0

Sie ein Element entfernen von ArrayList, während es iteriert und verursacht es zu werfen ConcurrentModificationException.

Lassen Sie uns Ihren Code verfolgen;

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

Dies erfordert Update() auf Item-Objekt, das ist:

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)); 
    } 

Achten Sie auf toBag(). Sie entfernen das Objekt Item aus Ihrer Sammlung, die Sie gerade bearbeiten.

Grundsätzlich müssen Sie einen Iterator verwenden, anstatt direkt aus der Arraylist zu entfernen.

Weitere Erläuterungen beziehen sich auf ähnliche Fragen auf dieser Seite: Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop

+0

Ich habe dies: für { \t \t \t Artikel item = iterator.next(); (Iterator iterator = Game.world.getItems() iterator();; iterator.hasNext().) \t \t \t if (Artikel == this) { \t \t \t \t iterator.remove(); \t \t \t} \t \t \t \t \t} jetzt, aber es wirft immer noch einen Fehler – Jakibah

+0

Sie haben es in Ihrer HandleItem Methode zu verwenden, und übergeben der Iterator, wo man irgendwie entfernen. – JuniorDev

0

Sie Item.toBag() diese Ausnahme verursacht. Die Zeile Game.world.getItems().remove(this); versucht, das Element aus der ArrayList zu entfernen.

Sie können keine Liste in einem für jede Schleife ändern. Sie können die remove-Methode nur aufrufen, wenn Sie den Iterator direkt verwenden.

Verwandte Themen