Java:Java.util.ConcurrentModificationException

Java:Java.util.ConcurrentModificationException,java,arraylist,Java,Arraylist,我正在制作2D,目前正在进行子弹射击。子弹是一个单独的类。所有项目符号都存储在名为“项目符号”的arraylist中。我试图让它在屏幕外侧(-16){ x-=移动速度; }否则{ ObjectHandler.记住要杀死(这个); } } //在ObjectHandler中: 私有HashSet kill_memory=new。。。; 公共空间{ this.kill_memory.add(this); } 私有void从_内存中杀死_(){ for(类型为\u对象的\u到\u kill obj:k

我正在制作2D,目前正在进行子弹射击。子弹是一个单独的类。所有项目符号都存储在名为“项目符号”的arraylist中。我试图让它在屏幕外侧(<-16)时破坏自己,但当我尝试时,它会给我这个错误

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at GameCanvas.updateMovement(GameCanvas.java:94)
at GameCanvas.gameLoop(GameCanvas.java:63)
at GameCanvas.<init>(GameCanvas.java:28)
at GameClient.<init>(GameClient.java:68)
at GameClient.main(GameClient.java:29)
updateMovement()方法:


为什么要这样做?谢谢。

当您在列表中迭代并试图同时从列表中删除/修改某个项目时,通常会引发此问题。我不确定到底发生了什么事。更多的代码示例可能会有所帮助。

之所以会出现这种情况,是因为您在迭代列表时正在修改列表

试着“记住”你需要的
kill
,在你通过整个列表后,检查你的“记忆”并执行相应的
kill
s。通过这种方式,您将在遍历列表后修改它

例如:

公共作废移动(){
如果(x>-16){
x-=移动速度;
}否则{
ObjectHandler.记住要杀死(这个);
}
}
//在ObjectHandler中:
私有HashSet kill_memory=new。。。;
公共空间{
this.kill_memory.add(this);
}
私有void从_内存中杀死_(){
for(类型为\u对象的\u到\u kill obj:kill\u内存){
ObjectHandler.bullets.remove(此);
}
ObjectHandler.kill_memory.clear();
}
//更新运动:
public void updateMovement(){
PlayerObject.update();
for(项目符号:ObjectHandler.bullets){
bullet.move();
}
ObjectHandler.kill_from_memory();
}

从堆栈跟踪中,我们可以看到您有一个方法,
gameLoop()
GameCanvas
中调用
updateMovement()
。后者迭代
main
线程中的项目符号。同时,您的
kill()
方法修改列表。这正是异常所说的,可以防止您受到进一步的损害


您必须同步访问
项目符号
列表或使用线程安全集合,如。

问题在于,您试图修改集合,同时在读取时删除元素。当然,这可能很危险,因此会抛出异常。如果使用
迭代器
,则可以利用其函数删除当前元素

大概是这样的:

public void updateMovement() {
    PlayerObject.update();

    Iterator<Bullet> iterator = ObjectHandler.bullets.iterator();
    while(iterator.hasNext()) {
        Bullet bullet = iterator.next();
        if(x > -16) {
            x -= move_speed;
        } else {
            iterator.remove();
        }
    }
}
public void updateMovement(){
PlayerObject.update();
Iterator Iterator=ObjectHandler.bullets.Iterator();
while(iterator.hasNext()){
Bullet=iterator.next();
如果(x>-16){
x-=移动速度;
}否则{
iterator.remove();
}
}
}

我们可能需要查看
updateMovement
源代码来帮助您。谢谢,是的,我使用了另一个ArrayList来存储射程之外的子弹,然后在移动循环后销毁它们。另外,请考虑使用其中之一,他们自动解决这个问题(尽管代价是线程安全)。
public void updateMovement() {
    PlayerObject.update();

    for(Bullet bullet : ObjectHandler.bullets) {
        bullet.move();


    }

}
public void move() {

    if(x > -16) {
        x -= move_speed;
    } else {
        ObjectHandler.remember_to_kill(this);
    }

}

// in ObjectHandler:

private HashSet<type_of_object_to_kill> kill_memory = new...;

public void remember_to_kill() {
    this.kill_memory.add(this);
}

private void kill_from_memory() {
    for (type_of_object_to_kill obj: kill_memory) {
        ObjectHandler.bullets.remove(this);
    }
    ObjectHandler.kill_memory.clear();
}

// update movement:

public void updateMovement() {
    PlayerObject.update();

    for(Bullet bullet : ObjectHandler.bullets) {
        bullet.move();
    }
    ObjectHandler.kill_from_memory();
}
public void updateMovement() {
    PlayerObject.update();

    Iterator<Bullet> iterator = ObjectHandler.bullets.iterator();
    while(iterator.hasNext()) {
        Bullet bullet = iterator.next();
        if(x > -16) {
            x -= move_speed;
        } else {
            iterator.remove();
        }
    }
}