从ArrayList中删除对象有时不起作用

时间:2018-01-10 20:36:23

标签: java eclipse arraylist

所以,我正在做一个坦克必须用子弹击落飞机的游戏。我有一个平面的ArrayList及其所有属性,我还有一个包含所有项目符号,它们的角度和坐标的ArrayList。

我在屏幕上显示所有平面的for循环,并更改了它们的坐标。在for循环内部,我创建了另一个环绕所有子弹的for循环。这是我显示子弹并更改其y和x坐标的位置。

对于ArrayList中的每个平面,有一个变量可以计算它与屏幕上所有项目符号的距离。我做到这一点,当子弹与飞机接触时,子弹和飞机都是他们的ArrayLists remove。然而,大约10-20%的时间,一架击中1架飞机的子弹移走了所有其他飞机,下一波飞机进来了。

有谁知道我的问题是什么?

以下是我的一些代码:

if(thisArrayList.size() > 0){

        for(int x = 0; x < thisArrayList.size(); x ++){

            if(thisArrayList.get(x)[4] == 1.0 && thisArrayList.get(x)[0] >= -50){

                g2d.drawImage(plane10, (int) (thisArrayList.get(x)[0] - 50), (int) (thisArrayList.get(x)[3] - 50), null);

            }else if(thisArrayList.get(x)[4] == 2.0 && thisArrayList.get(x)[0] >= -50){

                g2d.drawImage(plane20, (int) (thisArrayList.get(x)[0] - 50), (int) (thisArrayList.get(x)[3] - 50), null);

            }else if(thisArrayList.get(x)[4] == 3.0 && thisArrayList.get(x)[0] >= -50){

                g2d.drawImage(plane30, (int) (thisArrayList.get(x)[0] - 50), (int) (thisArrayList.get(x)[3] - 50), null);

            }

            thisArrayList.get(x)[0] += thisArrayList.get(x)[2];

            g2d.setFont(new Font("Source Sans Pro Black", 15, 15));

            g2d.setColor(Color.WHITE);

            g2d.drawString(((thisArrayList.get(x)[1])).toString(), (int) (thisArrayList.get(x)[0] - 10), (int) (thisArrayList.get(x)[3] + 7));

            if(thisArrayList.get(x)[0] >= Main.widthOfScreen + 50 && thisArrayList.get(x)[3] == 100){

                thisArrayList.get(x)[3] = 205.0;

                thisArrayList.get(x)[0] = -60.0;

            }else if(thisArrayList.get(x)[0] >= Main.widthOfScreen + 50 && thisArrayList.get(x)[3] != 100){

                if(thisArrayList.size() == 1){

                    isDone = "yes";

                    Panel.waveNum ++;

                    isVisible = false;

                    thisArrayList = new ArrayList<Double[]>();

                }else{

                    thisArrayList.remove(x);

                }

            }

            try{

                for(int i = 0; i < BulletTracker.bullets.size(); i ++){

                        //double dist = 100;

                        if(BulletTracker.bullets.size() > 0 && thisArrayList.size() > 0){

                            if(BulletTracker.bullets.size() > 0 && thisArrayList.size() > 0 && thisArrayList.get(x)[0] >= -50){

                                try{

                                    thisArrayList.get(x)[5] = Math.sqrt(((BulletTracker.bullets.get(i)[1] - thisArrayList.get(x)[0]) * (BulletTracker.bullets.get(i)[1] - thisArrayList.get(x)[0]))  
                                    + ((BulletTracker.bullets.get(i)[2] - thisArrayList.get(x)[3]) * (BulletTracker.bullets.get(i)[2] - thisArrayList.get(x)[3])));

                                }catch(Exception e){

                                    thisArrayList.get(x)[5] = 50.0;

                                }

                            }else{

                                thisArrayList.get(x)[5] = 100.0;

                            }

                            if(thisArrayList.get(x)[5] <= 50){

                                thisArrayList.get(x)[1] -= 10;

                                if(thisArrayList.get(x)[1] <= 0){

                                    if(thisArrayList.size() != 1){

                                        thisArrayList.remove(x);

                                    }else{

                                        isDone = "yes";

                                        Panel.waveNum ++;

                                        isVisible = false;

                                        thisArrayList = new ArrayList<Double[]>();

                                    }

                                }

                                BulletTracker.bullets.remove(i);

                            }

                        }

                    }

                    }catch(Exception e){

                        System.out.println("Sorry. There was an error.");

                        isDone = "yes";

                        Panel.waveNum ++;

                        isVisible = false;

                        thisArrayList = new ArrayList<Double[]>();

                    }

顺便说一句,thisArrayList是平面的ArrayList,thisArrayList.get(x)[5]是每个平面与所有子弹的距离。有很多不需要的try和catch语句以及我从未删除的不需要的代码。

1 个答案:

答案 0 :(得分:1)

我不确定,但看起来你的thisArrayList.remove内循环遍历thisArrayList

请看以下示例:

for(int x = 0; x < thisArrayList.size(); x++) {
    final int element = thisArrayList.get(x);
    if(condition) {
        thisArrayList.remove(x);
    }
}

如果满足条件,则删除元素,但由于您仍处于for循环中,因此执行以下操作:

假设我们有thisArrayList = { 1, 2, 3 }

  • 假设 x = 1 的条件为真,那么删除x = 1位置的元素
  • 您继续执行if
  • 之外的代码
  • 没有代码,因此循环增量 x 并继续
  • 现在我们已经 x = 2
  • 但由于 x = 1 处的元素已被删除,因此列表如下所示:{ 1, 3 }
  • 然后由于 x = 2 它的外部列表和for循环的条件:x < thisArrayList.size()为false

你知道它要去哪里......

问题是你应该尽量避免同时删除和迭代列表,因为它会导致跳过元素。

正确的解决方案是标记要移除的元素 它可以通过外部列表完成,例如List<int> toBeRemoved要删除索引。

  • 如果您要删除项目,请将其添加到toBeRemoved
  • 然后在整个for循环之后,循环遍历toBeRemoved并小心删除项目

或者你可以这样做:

if(condition) {
     thisArrayList.remove(x);
     --x;
     continue;
}

它将确保您不会跳过任何元素。

无论如何,迭代和删除同时更好的解决方案是使用迭代器:

Iterator<Integer> i = thisArrayList.iterator();
while (i.hasNext()) {
   int s = i.next(); // must be called before you can call i.remove()
   // Do something
   i.remove();
}

通过使用迭代器,您可以确保迭代每个元素,并且不会发生任何不良事件。

使用迭代器是一种很好的做法(不是每次都有,但在这种情况下!)