2016-07-14 78 views
2

我想避免併發修改異常。我循環一個實體HashMap來勾選()每個實體。玩家實體在屏幕上移動WASD輸入,並且當玩家向右移動時測試addNewEntity()方法,我打電話GameState.addNewEntity(new Explosion(true, this.x, this.y));。玩家出現幾次爆炸,然後出現錯誤。 Player類擴展了擴展Entity的Creature。 Explosion擴展了Entity類。試圖避免併發修改異常

此代碼是從我的遊戲狀態類:

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

我打勾()方法:

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

我addNewEntity方法:

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

我的渲​​染方法:

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

我試圖通過添加到newEntities HashMap而不是添加到實體HashMap來避免併發修改異常。在我的tick方法中,我循環遍歷newEntities的HashMap並將每個存在於其中的項目添加到實體中,並依次刪除每個項目。只有在這之後,我才能遍歷實體HashMap。

我是在迭代它的同時修改地圖的可能性如何?

回答

1

不允許使用增強for循環迭代它時直接從Map刪除條目。相反,使用顯式迭代器進行迭代,並使用迭代器的remove()方法。

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

對第二個循環做同樣的操作。

+0

謝謝伊蘭。像魅力一樣工作。 – Fabced