英文:
Why does this gives me an error (Multi Thread or ArrayList)?
问题
ArrayList<Nemico> nemici = o_orda.getNemici();
for (Nemico nemico : nemici) {
    if (Collisioni.ControllaCollisioni(o_navicella, nemico)) {
        nemici.remove(nemico);
        this.o_navicella.vita -= 10;
        break;
    }
    for (Proiettile pro : proiettili) {
        System.out.println("s1");
        if (Collisioni.CollsioniProiettile(pro, nemico)) {
            System.out.println("s2");
            nemici.remove(nemico);
            System.out.println("s3");
            proiettili.remove(pro);
            System.out.println("s4");
            break;
        }
        System.out.println("s5");
    }
    if (ControllaSconfitta()) {
        this.giocON = false;
        Disegna();
    }
}
This is the code, I'm sure it will help you.
This code is in a function that checks and updates everything every n milliseconds.
Thanks for the help
Exception in thread "Thread-7" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at java.lang.Thread.run(Thread.java:745)
and it freezes the game when the collision happens.
<details>
<summary>英文:</summary>
I have two threads which are running and I need to control if the bullet is touching the enemy but it gives me this problem where I printed "s4". Any idea what happened there? I'm quite a beginner. I'm using Java.
ArrayList<Nemico> nemici= o_orda.getNemici();
for (Nemico nemico : nemici) {
if(Collisioni.ControllaCollisioni(o_navicella, nemico)){
nemici.remove(nemico);
this.o_navicella.vita-=10;
            break;
        }
        for (Proiettile pro : proiettili){
            System.out.println("s1");
                if(Collisioni.CollsioniProiettile(pro, nemico)){
                    System.out.println("s2");
                    nemici.remove(nemico);
                    System.out.println("s3");
                    proiettili.remove(pro);
                    System.out.println("s4");
                    break;
                    
            }
                System.out.println("s5");
        }
       
        if(ControllaSconfitta()){
            this.giocON=false;
            Disegna();
        }
    }
This is the code, I'm sure it will help you. 
This code is in a function that checks and update everything every n millisecond.
Thanks for the help 
Exception in thread "Thread-7" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at java.lang.Thread.run(Thread.java:745)
and it freeze the game when the collsion happens.
</details>
# 答案1
**得分**: 1
_以下代码已经更新以使用Iterator.remove(),而不是ArrayList.remove()。感谢@PeterRader澄清了它们的使用方法。_
---
如果您在迭代ArrayList时打算对其进行修改,不应直接使用for-each循环进行迭代。有两种替代方法,一种是使用迭代器避免直接迭代ArrayList本身,另一种是使用Java 8的removeIf()函数。
我将给出一个简单(经过测试的)使用迭代器的示例,然后尝试修改您的代码以执行相同的操作:
**迭代器示例**
```java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class IteratorExample {
    public static void main(String[] args) {
        ArrayList<Integer> arrList = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
        // 获取一个迭代器以迭代arrList中的整数
        Iterator<Integer> iterator = arrList.iterator();
        // 当迭代器有下一个元素时,使用.next()访问此元素并将其打印出来。
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
修改您的代码以使用迭代器
对于此版本中可能存在的拼写错误或语法错误,我深感抱歉 - 我无法对其进行测试,但鉴于这只是一个小片段的代码,错误应该不会太多,希望您可以使用上述示例进行修复。 不要忘记也导入java.util.Iterator!
ArrayList<Nemico> nemici = o_orda.getNemici();
Iterator<Nemico> nemiciIterator = nemici.iterator();
while (nemiciIterator.hasNext()) {
    nemico = nemiciIterator.next();
    if (Collisioni.ControllaCollisioni(o_navicella, nemico)) {
        nemiciIterator.remove();
        this.o_navicella.vita -= 10;
        break;
    }
    Iterator<Proiettile> proIterator = proiettili.iterator();
    while (proIterator.hasNext()) {
        pro = proIterator.next();
        if (Collisioni.CollsioniProiettile(pro, nemico)) {
            nemiciIterator.remove();
            proIterator.remove();
            break;
        }
    }
    if (ControllaSconfitta()) {
        this.giocON = false;
        Disegna();
    }
}
...
资源
这是一个相关的资源。它还包括使用removeIf()的示例!https://www.baeldung.com/java-concurrentmodificationexception。
英文:
The below code has been updated to use Iterator.remove() instead of ArrayList.remove(). Thank you to @PeterRader for clarifying how these should be used.
If you are intending to modify an ArrayList while iterating over it, you should not use a for-each loop to iterate over it directly. There are two alternative approaches, using an iterator to avoid iterating over the ArrayList itself, or using Java 8's removeIf() function.
I will give a simple (and tested) example of using an iterator, and then attempt to modify your code to do the same thing:
Iterator Example
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class IteratorExample{
     public static void main(String []args){
         
        ArrayList<Integer> arrList = new ArrayList<Integer>(Arrays.asList(1,2,3));
        
        // Get an Iterator to iterate over the Integers in arrList
        
        Iterator<Integer> iterator = arrList.iterator();
        
        // While iterator hasNext element, access this element with .next() and print it. 
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        
        
     }
}
Modifying your code to use an iterator
Apologies for any spelling mistakes or syntax errors in this version - I have been unable to test it, but given it's only a small piece of code there shouldn't be many and hopefully you will be able to remedy them using the example above. Don't forget to import java.util.Iterator too!
ArrayList<Nemico> nemici= o_orda.getNemici();
Iterator<Nemico> nemiciIterator = nemici.iterator();
while (nemiciIterator.hasNext()) {
    nemico = nemiciIterator.next();
    if(Collisioni.ControllaCollisioni(o_navicella, nemico)){
        nemiciIterator.remove(nemico);
        this.o_navicella.vita-=10;
        break;
    }
    Iterator<Proiettile> proIterator = proiettili.iterator();
    while (proIterator.hasNext()) {
        pro = proIterator.next();
        if(Collisioni.CollsioniProiettile(pro, nemico)){
            nemiciIterator.remove(nemico);
            proIterator.remove(pro);
            break;
        }
    }
    if(ControllaSconfitta()){
        this.giocON=false;
        Disegna();
        }
    }
    ...
Resources
Here is a relevant resource. This also includes an example of using removeIf()! https://www.baeldung.com/java-concurrentmodificationexception.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论