0

I am working with single thread game, in Main class i have ArrayList to contain Bullet objects for attacking zombies. Each of frame of game i do loop like:

ArrayList<Bullet> bulletList;
for (Bullet iBullet : bulletList) {
    iBullet.move();
    iBullet.attack(bulletList);
}

In Bullet class, i wrote

public void attack(ArrayList<Bullet> bulletList) {
    for (Zombies z : zombieList) {
        if ( hit condition ) {
            bulletList.remove(this); //problem here
            return;
        }
    }
}

I got null error after first loop, seems bullet object had removed successfully from ArrayList and also made some confuses in loop of Main class.

  • 1
    Use `iterator` if you want to remove element from `List`. – vinS Dec 10 '17 at 05:26
  • @vinS It's worse than that. The iterator is still invalidated unless it's the *iterator* `remove` method that's used, so `bulletList.remove(this)` still kills the iterator. – Silvio Mayolo Dec 10 '17 at 05:28
  • 1
    You are tying to change `bulletList` while iterating over it. That is not possible. Iterate over a copy of the array list : `for (Bullet iBullet : new ArrayList(bulletList)) {` – c0der Dec 10 '17 at 05:29
  • I found that `for (int i=0; i < bulletList.size(); i++) {...}` work much more smoothly but i am just worry that the loop would omit next items in ArrayList if the previous one had been removed. – Nguyễn Phan Hùng Thuận Dec 10 '17 at 06:23
  • Check my updated answer. – Matt Dec 18 '17 at 10:34

1 Answers1

2

You can use an Iterator, changing your attack method to accept it as a parameter:

Iterator<Bullet> iterator = bulletList.iterator();
while (iterator.hasNext()) {
    Bullet iBullet = iterator.next();
    iBullet.move();
    iBullet.attack(bulletList, iterator);
}

public void attack(ArrayList<Bullet> bulletList, Iterator<Bullet> iterator) {
    iterator.remove();
}

Or you can change your attack method to return a boolean indicating whether the bullet hit or not (instead of removing the bullet), and use the removeIf() method introduced in Java 8:

for (Bullet iBullet : bulletList) {
    iBullet.move();
}
bulletList.removeIf(b -> b.attack());
Matt
  • 2,953
  • 3
  • 27
  • 46