Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 由于增强的for循环而导致ConcurrentModification错误_Java_For Loop_Arraylist - Fatal编程技术网

Java 由于增强的for循环而导致ConcurrentModification错误

Java 由于增强的for循环而导致ConcurrentModification错误,java,for-loop,arraylist,Java,For Loop,Arraylist,下面的代码导致线程“main”java.util.ConcurrentModificationException中出现异常 我正在尝试使用一个增强的for循环来迭代我的无人机阵列列表,以更新它们的位置和方向。以下代码仅适用于ArrayList中的1个无人机 tryToMove()获取无人机的方向,将其移动到相应的x、y位置,并检查其是否有效,如果无效,则改变方向 doDisplay()使用控制台中的无人机打印竞技场 public static void moveAllDrones(){

下面的代码导致线程“main”java.util.ConcurrentModificationException中出现异常

我正在尝试使用一个增强的for循环来迭代我的无人机阵列列表,以更新它们的位置和方向。以下代码仅适用于ArrayList中的1个无人机

tryToMove()
获取无人机的方向,将其移动到相应的x、y位置,并检查其是否有效,如果无效,则改变方向

doDisplay()
使用控制台中的无人机打印竞技场

public static void moveAllDrones(){
    String strOfCurrentDirection;
    Direction currentDirection;
        
    for (String drone : drones) {
        id = drones.indexOf(drone);
        System.out.println("Working on drone: " + id);
        String[] coords = drone.split(",");
        accX = Integer.parseInt(coords[0]);//get x coordinate
        accY = Integer.parseInt(coords[1]);// get y coordinate
            
        String droneWithCurrentID = drones.get(id); //direction in string
        strOfCurrentDirection = droneWithCurrentID.split(",")[2];
        currentDirection = Direction.valueOf(strOfCurrentDirection); //convert string to direction
            
            
        Drone.tryToMove(id, currentDirection, accX, accY);
    }
    DroneInterface.doDisplay();
}
我不知道为什么这个增强的for循环只适用于1架无人机。 谢谢你的帮助

更新:

public static void tryToMove(int id2, Direction accDir, int x1, int y1) {
        xPos = x1;
        yPos = y1;
        //Direction d = Drone.direction; // get current direction drone is facing.
        System.out.println("Trying to move drone, "+id2+ ". In the direction of: "+accDir);
        switch (accDir) {

        case NORTH: 
            yPos -= 1;
            if (DroneArena.canMoveHere(xPos, yPos)) {

                DroneArena.yRan = yPos;
                
            } else {
                yPos += 1;
                accDir = Direction.nextDirection();
            }
            DroneArena.updateDrone(id2, accDir, xPos, yPos);
            break;
        case EAST:

            xPos += 1;
            if (DroneArena.canMoveHere(xPos, yPos)) {

                DroneArena.xRan = xPos;


            } else {
                xPos -= 1;
                accDir = Direction.nextDirection();
            }
            DroneArena.updateDrone(id2, accDir, xPos, yPos);
            break;
        case SOUTH:

            yPos += 1;
            if (DroneArena.canMoveHere(xPos, yPos)) {
                DroneArena.yRan = yPos;

            } else {
                yPos -= 1;
                accDir = Direction.nextDirection();
            }
            DroneArena.updateDrone(id2, accDir, xPos, yPos);
            break;
        case WEST:

            xPos -= 1;
            if (DroneArena.canMoveHere(xPos, yPos)) {

                DroneArena.xRan = xPos;

            } else {
                xPos += 1;
                accDir = Direction.nextDirection();
            }
            DroneArena.updateDrone(id2, accDir, xPos, yPos);
            break;

        }
    }
更新无人机:

public static void updateDrone(int id2, Direction direction, int newX, int newY){

        updatedDirection = direction;
        DroneArena.direction = updatedDirection;
        drones.remove(id2);
        drones.add(id2, newX + "," + newY +"," + updatedDirection);

    }

CoModEx意味着一件事,而且只意味着一件事:

  • 您从集合C创建了一个迭代器I(而
    for(ta:C)
    正在创建一个
    C
    的迭代器)
  • 在稍后的某个时间点,集合C会以某种方式被修改(而不是通过迭代器I的
    .remove()
    方法)
  • 您可以以任何方式与I交互:调用其中的任何方法,或者点击
    for(ta:c)
    循环(您到达循环的末尾,或者在循环中运行
    continue;
  • 你在这里就是这样做的:当你启动for循环时,你对
    无人机
    做一个迭代器,修改
    无人机
    ,然后你迭代循环(因为
    tryToMove
    修改无人机)

    你不能这么做,原因应该很明显:这到底是什么意思?如果你迭代
    [1,2,3,4,5]
    2
    的迭代过程中,您删除了
    3
    ,那么3应该被跳过吗?如果在
    2
    的迭代过程中,您删除了
    1
    ?如果3应该被跳过,但是1已经完成并且不能被跳过,这意味着什么?另外,尝试跟踪已删除的内容是非triv的ial(通常您只需要使用索引,但如果您在循环的中途开始删除早期的元素,这会变得很棘手),这也是为什么它会这样工作的第二个原因:在迭代集合时,您不能修改它

    那么,你如何解决这个问题呢

    最简单的方法是先复制无人机,然后在副本中迭代。这样,在循环过程中所做的任何修改都不会影响您的副本,因此不会导致共索引。请注意,这当然意味着您所做的任何修改在循环过程中都不可见

    第二个选项(仅适用于基于索引的快速查找的ArrayList或其他构造)是使用旧样式的for循环,并手动管理索引变量

    第三种方法是使用具有明确定义的行为的集合类型(例如
    CopyOnWriteArrayList
    ),它执行列表本身内置的第一个选项

    第四种方法是重新设计您正在做的事情,以便修改基础集合不再是其中的一部分

    第五种方法是在迭代过程中存储您希望对列表执行的所有操作,然后在迭代之后应用它们


    还有10亿个-这取决于您尝试执行的操作。

    当您在对集合进行迭代时修改集合时,会抛出一个
    ConcurrentModificationException
    。您显示的代码不会修改
    无人机
    集合,因此抛出
    ConcurrentModificationException
    的原因必须在
    Drone.tryToMove()
    是否修改
    Drone.tryToMove()
    中的任何字符串?
    Drone
    我们也需要查看该方法,以帮助您。@CharlieArmstrong`tryToMove()调用updateDrone()它删除具有相应id的arrayList,然后向列表中添加具有相同id但为new的新元素values@ThomasKläger将更新问题以显示方法好了,你在迭代ArrayList时修改了它。是相关文档。我通过谷歌搜索“Java ConcurrentModificationException”找到了它。如果StackOverflow不是那么禁忌的话,我会发布一个LMGTFY链接。我如何才能将其更改为循环的标准?我太远了,无法重新设计该方法,因为我的最后期限很近。非常遗憾。感谢您提供的详细答案。将ArrayList更改为CopyOnWriteArrayList将其排序…感谢您的帮助!