从ArrayList中删除对象会导致延迟

时间:2012-02-15 12:15:47

标签: java android arraylist

我有一个 ArrayList ,它在我的安卓游戏中拥有Planes(敌人)。这些平面从屏幕的一侧移动到另一侧,用户必须躲避它们。当平面的x值小于-50时,它将从ArrayList中删除。当发生这种情况时,它会导致当前屏幕上的所有平面略微“跳跃”。它们消失了几毫秒然后被重新绘制,但是它们应该落后于它们的2px。

这是paint方法,其中planes是ArrayList

public void onDraw(){
        bg1.onDraw(c);
    bg2.onDraw(c);
    chopper.onDraw(c);

    score.onDraw(c);

    // PAINTS THE PLANE OR DELETES IF OFF SCREEN
    for (int i = 0; i < planes.size(); i++) {
        Plane p = planes.get(i);
                    if(p.getX()<-50){
                            planes.remove(p);
                    }else{
                            p.onDraw(c);

                            if (p.getX() < 170) {
                                    detectPlaneCollision(p, c);
                            }
                    }

           }
}

有没有办法解决这个问题?我应该使用不同的数据结构吗?

由于

汤姆

3 个答案:

答案 0 :(得分:1)

我认为您的问题与您选择的数据结构无关,而是因为您在循环时修改了List

想象一下你的列表中有三架飞机 - [P1,P2,P3]。

  • 在循环的第一次迭代i0时,您处理P1
  • P1有getX() < -50所以你删除它,现在列表[P2,P3]
  • 在循环的下一次迭代i现在是1,因此您处理P3。
  • 这意味着P2永远不会被处理,因此永远不会被绘制,使其短暂消失。

尝试使用Iterator,这样您就可以在循环List时安全地删除项目。

Iterator<Plane> i = planes.iterator();

while (i.hasNext()) {
  Plane p = i.next();

  if (p.getX() < -50) {
    i.remove();
  } else {
    p.onDraw(c);

    if (p.getX() < 170) {
      detectPlaneCollision(p, c);
    }
  }
}

但是,由于您不关心处理Plane主题的顺序,因此可以考虑将其存储在Set而不是List中。 Set在添加和删除项目时不必担心维护项目的顺序。

答案 1 :(得分:0)

如果您从列表中进行大量删除和添加,请考虑使用LinkedList。如果数据集中的变化非常小,则ArrayList更合适。

尽管您还必须考虑从LinkedList获取元素的速度比ArrayList慢一些,因此在使用LinkedList时请记住这一点。

答案 2 :(得分:0)

我认为该代码中存在错误。

如果移除i==0planes[0]会怎样?

planes[n]将进入planes[n-1]位置。例如。 planes[1]将进入planes[0]位置。

然后i会增加,所以i==1

因此,原始的planes[1](现在为planes[0])将被跳过。