【问题标题】:Removing Object from ArrayList causes lag从 ArrayList 中删除对象会导致延迟
【发布时间】:2012-02-15 12:15:46
【问题描述】:

我有一个 ArrayList,它在我的 Android 游戏中保存了飞机(敌人)。这些平面从屏幕的一侧移动到另一侧,用户必须躲避它们。当平面的 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);
                            }
                    }

           }
}

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

谢谢

汤姆

【问题讨论】:

  • 你为什么不花 10 秒钟的时间来正确地格式化你的代码
  • 我试过了,输入时格式正确,不知道为什么会这样。

标签: java android arraylist


【解决方案1】:

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

假设您的列表中有三个平面 - [P1,P2,P3]。

  • 在循环i0 的第一次迭代中,您处理P1
  • P1 有 getX() &lt; -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 不必担心在添加和删除项目时维护它们的顺序。

【讨论】:

  • 非常感谢,我试过了,它奏效了。我以前从未听说过/使用过迭代器,所以谢谢你给我看这个!
  • 现在您只需要在修改列表时使用迭代器。否则你可以说for (Plane p : planes) { ... }
【解决方案2】:

如果您要从列表中删除和添加大量内容,请考虑使用LinkedList。如果数据集变化很小,ArrayList 更合适。

虽然您还必须考虑这样一个事实,即从 LinkedList 获取元素比从 ArrayList 获取元素要慢一些,因此在使用 LinkedList 时请记住这一点。

【讨论】:

    【解决方案3】:

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

    如果i==0planes[0] 被删除怎么办?

    planes[n] 将移动到位置planes[n-1]。例如。 planes[1] 将移动到planes[0] 的位置。

    然后i 递增,所以i==1

    因此原来的planes[1](现在是planes[0])将被跳过。

    【讨论】:

    • 啊,当然,这可以解释跳过,因为 planes[0] 总是被删除!
    猜你喜欢
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    • 2015-08-02
    相关资源
    最近更新 更多