Search code examples
javaarraylistgame-physics

cannot delete list elements


I am making space invaders in Java. I am trying to get lasers to work but whenever I remove a laser the timer (that the code is in) stops. I don't understand the error. Here is the error:

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
    at GraphicsPanel$1.actionPerformed(GraphicsPanel.java:60)
    at java.desktop/javax.swing.Timer.fireActionPerformed(Timer.java:310)
    at java.desktop/javax.swing.Timer$DoPostEvent.run(Timer.java:242)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Here is the script that the error is on:

for(Laser l : lasers) { //the error is on this line
  l.y+=l.dy;
                
  if(l.y < 0)
    lasers.remove(l);

  for(Alien a : aliens) {
    if(l.getHitbox().intersects(a.getHitbox())
      aliens.remove(a);
      lasers.remove(l);
  }

}

Does anyone know why this happens? I can send all code if it is necessary. Thanks


Solution

  • Java does not allow removing elements from a collection while you are iterating it using a for-each loop.

    Javadoc for ConcurrentModificationException

    Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception

    Possible solutions:

    Use iterator explicitly

    use Iterator explicitly and then remove the element you want.

    Iterator<Alien> alienIterator = aliens.iterator();
    while (alienIterator.hasNext()){
      Alien alien = alienIterator.next();
      if(laser.getHitbox().intersects(alien.getHitbox()) {
        alienIterator.remove();
        laserIterator.remove();
      }
    }
    

    You can find other solutions here