我的问题很简单,我有一个BodyList(称为body),它会更新,将列表传递给每个元素。在某些情况下,一个正文需要销毁自己和ArrayList中的另一个正文。我让他们用isRequestingDeath
布尔做“自杀”,我可以在第7行成功删除它们,并且对于移除其他物体的物体,它将整数requestedMurder
设置为其他物体的位置尸体清单。然后使用bodies
ArrayList remove()
方法尝试删除该元素(或者在本例中为“body”)。
for(Iterator<Body> bodyIt = bodies.iterator(); bodyIt.hasNext();) {
Body body = bodyIt.next();
body.Update(bodies, gravConstant);
if(body.isRequestingDeath) {
bodies.remove(body.requestedMurder);
bodyIt.remove();
}
}
我得到的错误:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.remove(Unknown Source)
at gravity.SimApp.Update(SimApp.java:67)
at gravity.SimApp.Loop(SimApp.java:53)
at gravity.SimApp.<init>(SimApp.java:42)
at gravity.SimApp.main(SimApp.java:86)
有没有办法修复我的方法?或者是否有更好的方法让ArrayList中的元素移除自己/彼此
答案 0 :(得分:0)
CME就是这样:两件或两件以上的东西试图一次修改bodies
。这在您的代码中看起来并不明显(看起来非常好),但这是错误Exception
的定义。
我的猜测是bodies
适用于Model-View-Controller架构的“模型”组件(可能是游戏?),并且它在其他地方同时进行修改,例如由控制器。尝试找到一种简化软件的方法,以避免并发修改(例如基于事件)或手动或通过Collections.synchronizedList()
同步bodies
。
答案 1 :(得分:0)
问题在于这一行:
bodies.remove(body.requestedMurder);
因为你在这里试图从底层集合中删除一个元素。 Iterator#remove()
是在迭代期间从基础集合中删除项目的唯一安全方法。如果在迭代中以任何其他方式修改基础集合,则未指定行为。
要解决此问题,您可以填充单独的要删除的项目列表,如下所示:
List<Body> bodiesToRemove = new ArrayList<Body>();
for(Iterator<Body> bodyIt = bodies.iterator(); bodyIt.hasNext();) {
Body body = bodyIt.next();
body.Update(bodies, gravConstant);
if(body.isRequestingDeath) {
bodiesToRemove.add(body); // add in to be removed list
bodyIt.remove();
}
}
// now remove all from original list
bodies.removeAll( bodiesToRemove );
答案 2 :(得分:-1)
我认为您的问题似乎没问题,但根据java集合行为,它似乎在逻辑上是错误的。 例如 : requestedMurder是列表中其他元素的位置值,删除任何元素后可能不正确,因为列表将被缩小。
所以我认为虽然不可能根据你的&#34;身体&#34;同时使用位置值同时删除自我和其他元素。对象....如果我不对,请纠正我。
答案 3 :(得分:-1)
我最后只是对传递到每个身体的bodies
副本进行了必要的编辑,并且工作正常。 (虽然我不确定这是否合适/安全)