当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
您无法在迭代时更改集合。
List<Entity> entitiesToRemove = new ArrayList<>();
for (Entity entity : entities) {
entity.render(shader, camera, this);
if (!entity.isActive()) {
entitiesToRemove.add(entity);
}
}
entities.removeAll(entitiesToRemove);
使用正确的
java.util.ConcurrentModificationException
方法时显示的[remove()
实际上,您使用了错误的方法。或者更准确地说是remove()
方法在错误的对象上。
您可以在迭代时删除元素,但是需要在remove()
对象上使用Iterator
方法;有关更多详细信息,请参见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
迭代器确实实现了它。
来自 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();) {
if (it.next().isActive()) {
it.remove();
}
}