【问题标题】:java.util.ConcurrentModificationException displaying when using the correct remove() method [duplicate]使用正确的 remove() 方法时显示 java.util.ConcurrentModificationException [重复]
【发布时间】:2020-03-24 13:13:21
【问题描述】:

当 isActive 为 false 时,我正在尝试删除实体。当实体属性isActive设置为false时,它进入if语句并删除实体,之后再次遍历实体列表然后崩溃。根据我的研究,我正在使用正确的方法从数组列表中删除一个对象。

删除实体并遍历列表时的代码是

    for (Entity entity : entities) {// itaarate through all the entities in list of entities

        entity.render(shader, camera, this);// render each entity

        if (!entity.isActive())// checks if entity attribute is active
            entities.remove(entity);// removes entity from list

    }

在从列表中删除实体后使用调试器时,它会返回到 for 循环的顶部,然后显示此页面

调试时的变量窗口

控制台中显示的完整错误是

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at project.World.render(World.java:196)
at project.Main.<init>(Main.java:152)
at project.Main.main(Main.java:167)

正在创建的列表是

public static ArrayList<Entity> entities; // contains all entities

【问题讨论】:

标签: java exception arraylist concurrentmodification


【解决方案1】:

使用正确的remove()方法时显示java.util.ConcurrentModificationException

其实你用错了方法。或者更准确地说是错误对象上的remove() 方法。

你可以在迭代的时候移除一个元素……但是你需要在Iterator对象上使用remove()方法;有关详细信息,请参阅javadoc

Iterator<Entity> it = entities.iterator();
while (it.hasNext()) {
    Entity entity = it.next();
    entity.render(shader, camera, this);

    if (!entity.isActive()) {
        it.remove();
    }
}

注意Iterator.remove() 是一个可选操作,但ArrayList 迭代器确实实现了它。

ListIterator API 具有相同的方法,但Iterator 更通用。 (您可以将上述示例代码用于任何可以使用Iterator 迭代的类型,而不仅仅是List 类型。)

【讨论】:

    【解决方案2】:

    您不能在迭代时更改集合。

    List<Entity> entitiesToRemove = new ArrayList<>();
    
    for (Entity entity : entities) {
        entity.render(shader, camera, this);
    
        if (!entity.isActive()) {
            entitiesToRemove.add(entity);
        }
    }
    
    entities.removeAll(entitiesToRemove);
    

    【讨论】:

      【解决方案3】:

      来自 official java list tutorial

      for (ListIterator<E> it = list.listIterator(); it.hasNext();) {
          if (val == null ? it.next() == null : val.equals(it.next())) {
              it.remove();
          }
      }
      

      使示例适应您的代码:

      for (ListIterator<Entity> it = entities.listIterator(); it.hasNext();) {
          Entity entity = it.next();
          entity.render(shader, camera, this);    
          if (entity.isActive()) {
              it.remove();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-03
        • 1970-01-01
        • 1970-01-01
        • 2011-04-15
        • 2021-07-27
        • 1970-01-01
        • 2013-03-27
        相关资源
        最近更新 更多