2014-06-19 41 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

我把你的第一个解决方案(我的代码已经非常超载),最小的代码是最有可能的(目前).. 非常感谢,完美的作品。 –