исключение ArrayList IndexOutOfBoundsException для Android

#java #android #andengine

#java #Android #и инженер

Вопрос:

Я создаю игру для Android с помощью AndEngine. У меня есть arraylist спрайтов, и при каждом обновлении я хочу проверять, столкнулся ли спрайт проигрывателя с каким-либо из них. Но этот отрывок моего кода вызывает у меня головную боль:

 public void onUpdate(final float pSecondsElapsed) {
    sprites.addAndRemove();
    for (int i=0;i<sprites.size();i  ) {
        if(playerSprite.collidesWith(sprites.get(i))) {
            sprites.setToRemove(i); 
            //adds the sprite to a removal queue arraylist. 
            //the actual sprites arraylist is not touched until addAndRemove() fires.
        }
    }
}
  

Выглядит довольно просто, но почему-то sprites.get(i) выдает это:

 E/AndroidRuntime(  883): FATAL EXCEPTION: UpdateThread
E/AndroidRuntime(  883): java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
  

Несмотря на i<sprites.size() , я каким-то образом достигаю значения sprites.size() . Я помещаю сообщения журнала на каждой итерации с указанием размера arraylist и текущего значения i, и это кажется правильным:

 D/app(  883): size is 4
D/app(  883): i is 0
D/app(  883): size is 4
D/app(  883): i is 1
D/app(  883): size is 4
D/app(  883): i is 2
D/app(  883): size is 4
D/app(  883): i is 3
  

…за которым немедленно следует исключение.

Итак, я в тупике, как это может произойти?

 W/dalvikvm(  883): threadid=9: thread exiting with uncaught exception (group=0x40015560)
E/AndroidRuntime(  883): FATAL EXCEPTION: UpdateThread
E/AndroidRuntime(  883): java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
E/AndroidRuntime(  883):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
E/AndroidRuntime(  883):    at java.util.ArrayList.get(ArrayList.java:311)
E/AndroidRuntime(  883):    at org.anddev.andengine.entity.Entity.onManagedUpdate(Entity.java:776)
E/AndroidRuntime(  883):    at org.anddev.andengine.entity.Entity.onUpdate(Entity.java:648)
E/AndroidRuntime(  883):    at org.anddev.andengine.entity.Entity.onManagedUpdate(Entity.java:776)
E/AndroidRuntime(  883):    at org.anddev.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:261)
E/AndroidRuntime(  883):    at org.anddev.andengine.entity.Entity.onUpdate(Entity.java:648)
E/AndroidRuntime(  883):    at org.anddev.andengine.engine.Engine.onUpdateScene(Engine.java:494)
E/AndroidRuntime(  883):    at org.anddev.andengine.engine.Engine.onUpdate(Engine.java:489)
E/AndroidRuntime(  883):    at org.anddev.andengine.engine.Engine.onTickUpdate(Engine.java:465)
E/AndroidRuntime(  883):    at org.anddev.andengine.engine.Engine$UpdateThread.run(Engine.java:684)
  

Комментарии:

1. можете ли вы опубликовать полный код цикла for и дополнительную часть журнала ошибок?

2. отредактированный, я поместил весь метод onUpdate целиком

Ответ №1:

Способ 1:

 for(Sprite sprite : sprites){
   if (playerSprite.collidesWith(sprite)) {
      //--
   }
}
  

Способ 2:

 for (Iterator<Sprite> i = sprites.iterator(); i.hasNext();) {
      if (playerSprite.collidesWith(i.next())) {
         //--
      }
}
  

Метод 1 более предпочтителен.

Комментарии:

1. какой метод вы пробовали, попробуйте прокомментировать весь код внутри цикла и просто распечатать спрайт объекта