2016-07-14 6 views
2

Ich versuche, die gleichzeitige Änderung Ausnahme zu vermeiden. Ich Schleife über eine Entity HashMap zu Tick() jeder Entität. Player Entity bewegt sich um den Bildschirm mit WASD-Eingabe, und zum Testen addNewEntity() Methode rufe ich GameState.addNewEntity(new Explosion(true, this.x, this.y));, wenn Spieler nach rechts bewegt. Einige Explosionen erscheinen über Spieler und dann erhalte ich einen Fehler. Die Spielerklasse erweitert Kreatur, die Entität erweitert. Explosion erweitert die Entity-Klasse.versuchen zu vermeiden, gleichzeitige Ausnahmefehler

Dieser Code ist von meiner GameState Klasse:

private static HashMap<Integer, Entity> entities = new HashMap<Integer, Entity>(); 
private static HashMap<Integer, Entity> newEntities = new HashMap<Integer, Entity>(); 

player = new Player(game, true, 100, 100); 
entities.put(0, player); 

Mein tick() -Methode:

public void tick() { 
    // add new elements from newEntities to entities, deleting from newEntities 
    for (Entry<Integer, Entity> entry : newEntities.entrySet()) { 
     entities.put(entities.size(), entry.getValue()); 
     newEntities.remove(entry.getValue()); 
    } 

    System.out.println(entities.size()); 

    // tick the updated entities HashMap 
    for (Entry<Integer, Entity> entry : entities.entrySet()) { 
     entry.getValue().tick(); 

     // remove dead entities 
     if (!entry.getValue().isAlive) { 
      entities.remove(entry.getKey()); 
     } 
    } 
} 

meine addNewEntity Methode:

public static void addNewEntity(Entity e) { 
    // add a new element to newEntities. 
    newEntities.put(newEntities.size(), e); 
} 

meine Render-Methode:

public void render(Graphics g) { 
    for (Entry<Integer, Entity> entry : entities.entrySet()) { 
     entry.getValue().render(g); 
    } 
} 

Ich habe versucht, die Concurrent Modification-Ausnahme zu vermeiden, indem Sie die Hash-Map newEntities hinzufügen, anstatt die Entitäten HashMap hinzuzufügen. In meiner Tick-Methode schleife ich die newEntities-HashMap und füge jedes Element, das dort existiert, zu den Entitäten hinzu und lösche jedes Element nacheinander. Erst danach schleife ich die Entitäten HashMap.

Wie ist es möglich, dass ich die Karte ändere, während ich darüber Iteriere?

Antwort

1

Das direkte Entfernen eines Eintrags aus einer Map während des Iterierens mit der erweiterten for-Schleife ist nicht zulässig. Verwenden Sie stattdessen einen expliziten Iterator zum Iterieren und die Methode remove() des Iterators.

Iterator<Map.Entry<Integer, Entity>> iter = newEntities.entrySet().iterator(); 
while (iter.hasNext()) { 
    Map.Entry<Integer, Entity> entry = iter.next(); 
    entities.put(entities.size(), entry.getValue()); 
    iter.remove(); 
} 

Machen Sie dasselbe für die zweite Schleife.

+0

Danke Eran. Lief wie am Schnürchen. – Fabced