2014-06-19 63 views
-1

我在我的Android項目中爲列表的每個循環使用了一些麻煩。這個錯誤是由一個迭代器產生的(或者我最好說「錯誤是由我做的 - 不知道如何使用迭代器」^^)。列表循環遍歷以便在畫布上繪製子彈對象。當其中一顆子彈離開屏幕時,我刪除這個對象。每個Java都有問題

使用 「正常」 的for循環解決的錯誤:

for (int ii = 0; ii < bulletList_P1.size(); ii++) 
       bulletList_P1.get(ii).draw(canvas); 

此實現帶來的錯誤:

for (Bullet bullet : bulletList_P1) 
       bullet.draw(canvas); 

我發現THIS這裏計算器。與我的問題不同的是,在這種情況下創建了新的對象 - 我的問題是現在如何處理這種情況時,對象被刪除(從列表中刪除)。

使用一個或另一個實現的性能差異有多大?

+3

問題其實是完全一樣的。當您使用for-each循環遍歷它時,不能在結構上修改集合。期。只要你不使用'LinkedList',性能可能是相同的。我還想指出,你的「正常」for循環有可能跳過元素。另外,你在哪裏取出子彈?在draw()中? – awksp

+0

您可以使用'iterator'在'for-each'循環中移除元素。此問題已被解決http://stackoverflow.com/questions/6958478/modifying-a-collection-while-iterating-using-for-each-loop –

+1

閱讀[ForLoopWorking](http://stackoverflow.com/questions/19511956/java-for-each-loop-working),以便更好地理解如何處理刪除方案,如問題的最後部分所述..... – dbw

回答

1

在迭代它時,通常無法修改集合。圍繞此的策略通常落入:

i。複製/克隆原始集合純粹是爲了遍歷它,而您更改原始集合。

for (Bullet bullet : new ArrayList<Bullet>(bulletList_P1)) 
    bullet.draw(canvas); 

(甚至更好的是,使用番石榴庫的ImmutableList.copyOf法)

II。在迭代過程中收集你的突變,並有一個單獨的階段來應用突變。對於你的例子,你可能會創建一組在子句階段離開屏幕的子彈。然後使用removeAll在最後刪除錯誤的子彈。

ArrayList<Bullet> removals = new ArrayList<Bullet>(); 
for (Bullet bullet : bulletList_P1) 
    if (!bullet.draw(canvas)) 
     removals.add(bullet); 
bulletList_P1.removeAll(removals); 

iii。使用迭代器並在遍歷它時使用迭代器的remove方法修改集合。

for (Iterator<Bullet> iterator = bulletList_P1.iterator(); iterator.hasNext();) { 
    Bullet bullet = iterator.next(); 
    if (!bullet.draw(canvas)) 
     iterator.remove(); 
} 
+0

我把你的第一個解決方案(我的代碼已經非常超載),最小的代碼是最有可能的(目前).. 非常感謝,完美的作品。 –