简体   繁体   English

java ArrayList中的ConcurrentModificationException

[英]ConcurrentModificationException in java ArrayList

I have the following code running on the only thread: 我在唯一的线程上运行以下代码:

ArrayList<Ball> allBalls; 
ArrayList<Ball> toRemove = new ArrayList<Ball>();

for (Ball ball:allBalls) { //Exception thrown here
    ball.move();

    if (shouldRemove(ball)) {
        toRemove.add(ball);
    }
}               
allBalls.removeAll(toRemove);       
toRemove.removeAll(toRemove);

Sometimes it throws 有时会抛出

java.util.ConcurrentModificationException
  at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)

But when I replace this line 但是当我替换这条线时

for (Ball ball:allBalls) {

by this 这样

for (int i=0; i<allBalls.size();i++) {
    Ball ball = allBalls.get(i);

No exception is thrown. 没有异常被抛出。

Why? 为什么?

Only reason you are getting this exception is that your collection is getting modified in loop/iteration (I think move method is modifying object which will get reflected in list). 收到此异常的唯一原因是您的集合在循环/迭代中被修改(我认为move方法正在修改对象,该对象将反映在列表中)。

To explain why you are getting exception in foreach but not in for : 解释为什么您在foreach中获得异常,但在for中却没有获得异常:

foreach loop uses iterator internally. foreach循环在内部使用迭代器。 And collections are fail fast (immediately report failure), as a result of which next() method of iterator will throw exception if you collection is getting modified in the loop. 并且集合很快就会失败(立即报告失败),因此,如果在循环中对集合进行修改,则迭代器的next()方法将引发异常。 However normal for loop does not use iterator , so that is reason you are not getting exception in that loop but there be other side effects of modifying in for loop like size getting changed or iteration becoming infinite. 但是,正常的for循环不使用迭代器,因此这就是您没有在该循环中获得异常的原因,但是在for循环中进行修改还有其他副作用,例如更改大小或使迭代变为无限。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM