2016-03-14 55 views
-3

因此,我有一個存儲關於宇宙的不同對象(行星,彗星,星等)的數組列表。而不是這樣做:遊戲的每一次迭代我希望它減少1 0

planet.decreaseLifeTime(1); 
star.decreaseLifeTime(1); 
comet.decreaseLifeTime(1); 

遊戲的每一次迭代,我希望它由1減少生活時間,我試過,但它不工作:

private ArrayList<SpaceObject> universeEntities; 

public void reduceLifeTime() { 
    for (SpaceObject entity: universeEntities) { 
     entity.decreaseLifeTime(1); 
     if(entity.getLifeTime() <= 0) { 
      erase(entity); 
      System.out.println("This entity has been erased"); 
     } 

     System.out.println("life time: " + entity.getLifeTime()); 
    } 
} 

對象添加像這樣:

planet = new Planet(500, 500, -2, -2, 25, Color.BLUE, this); 
universeEntities.add(planet); 
+2

你的問題是什麼? – epoch

+2

行'擦除(實體)'是否更改'universeEntities'列表? –

+0

它只減去1,即生命期(這是一個整數)一次。然而,我希望它不斷減去1,直到達到0. – COLONELXO

回答

1

如果erase(entity)正在修改universeEntities列表,java將會發瘋。

您可以將要擦除的SpaceObject存儲在單獨的列表中,然後在for循環之後將其擦除。

你也可以遍歷該universeEntities而不使用迭代 例如一個數字索引

+1

這是我開始編程時犯的一個錯誤,我仍然偶爾忘記刪除項目會擾亂迭代週期。但是請詳細說明他正在進行擦除的方式有什麼問題,以及Java究竟是如何「瘋狂」的。 –

+1

根據Java API文檔[API 2014],如果在迭代過程中修改了基礎集合,則未指定迭代器的行爲。 – leumas95

+1

刪除迭代器當前指向的條目時,這一點尤爲重要。幾乎每個iterable的實現都會遇到問題。 –

1

根據你實施的reduceLifeTime方法,問題可能在於調用erase方法(取決於它是如何實現的)。

如果erase方法只是試圖通過調用ArrayList的remove方法從universeEntities集合中刪除一個項目,它只是破壞一個迭代器。

考慮重新實現你的方法:

public void reduceLifeTime() { 
    Iterator<SpaceObject> iterator = universeEntities.iterator(); 
    while (iterator.hasNext()) { 
     SpaceObject object = iterator.next(); 
     object.decreaseLifeTime(1); 

     if(object.getLifeTime() <= 0) { 
      iterator.remove(); 
      System.out.println("This entity has been erased."); 
     } 

     System.out.println(String.format("Life time: %d", object.getLifeTime())); 
    } 
} 

完全工作示例:

public class Test { 
    private ArrayList<SpaceObject> universeEntities = new ArrayList<SpaceObject>(); 

    public Test() { 
     universeEntities.add(new Planet()); 
     universeEntities.add(new Planet()); 
    } 

    public void reduceLifeTime() { 
     Iterator<SpaceObject> iterator = universeEntities.iterator(); 
     while (iterator.hasNext()) { 
      SpaceObject object = iterator.next(); 
      object.decreaseLifeTime(1); 

      if(object.getLifeTime() <= 0) { 
       iterator.remove(); 
       System.out.println("This entity has been erased."); 
      } 

      System.out.println(String.format("Life time: %d", object.getLifeTime())); 
     } 
    } 

    public static void main(String[] args) { 
     Test test = new Test(); 

     while(true) { 
      test.reduceLifeTime(); 
      // Endless loop. Need a quit condition. 
     } 
    } 

    public static class SpaceObject { 
     protected int life = 0; 

     public SpaceObject(int life) { 
      this.life = life; 
     } 

     public void decreaseLifeTime(int value) { 
      this.life -= value; 
     } 

     public int getLifeTime() { 
      return life; 
     } 
    } 

    public static class Planet extends SpaceObject { 
     public Planet() { 
      super(10); 
     } 
    } 
} 

如果你不想使用迭代器,你可以收集應該被刪除的項目在某種收集中,從reduceLifeTime方法返回,然後使用removeAll刪除。