为什么Iterator.next()抛出ConcurrentModificationException

时间:2011-05-20 04:54:21

标签: java iterator while-loop

勉强的是,这段小代码抛出了上面提到的异常。 此外,查看网络上发布的代码似乎是正确的:

import java.util.ArrayList;
import java.util.Iterator;

public class IteratorTest {

    ArrayList<Integer> arr = new ArrayList<Integer>();

    Iterator i = arr.iterator();

    public void show() {
        arr.add(2);
        arr.add(5);
        arr.add(9);

        while(i.hasNext()){
            System.out.println(i.next());
        }
    }
}

有什么建议吗? 感谢

4 个答案:

答案 0 :(得分:13)

这个电话:

Iterator i=arr.iterator();

应该是在完成对ArrayList的所有写入之后。

所以在您的代码中,在开始迭代之前执行此操作:

Iterator i=arr.iterator();
while(i.hasNext()) {
...
}

答案 1 :(得分:4)

这是因为您已经修改了通过iterator()获取Iterator并调用next()之间的支持列表。

Iterator的典型用法是:

for (Iterator<Integer> iter=arr.iterator(); iter.hasNext(); ) {
    Integer element = iter.next();
}

或者更好的是,使用新的for-each循环:

for (Integer element: arr) {
}

确保在循环外对集合执行添加。

答案 2 :(得分:2)

您正在实例化对象Iterator时定义IteratorTest。然后,您将一些数据添加到ArrayListarr

您现在已经修改了列表,因此Iterator的状态无效。

您无法使用Iterator并在不使用ArrayList的情况下更改Iterator

答案 3 :(得分:0)

答案4在技术上是正确的,但不是因为每个&#34; for(;;)或&#34;使用循环而不是while()循环。它只是Iterator在Class中声明的范围而不是方法的问题。首先,让我们看一下hasNext()next()两种方法的行为:

hasNext()方法只是查询内部游标(索引); next()实际上使光标前进,因此这是&#34;修改&#34;这可能会引发异常。如果您尝试使用在使用next()的方法之外声明和分配的Iterator,则代码将在第一个next()上抛出异常,无论它是否为{{1} }或for(;;)

在答案4和8中,迭代器在方法中本地声明和使用。它恰好发生了,因为while()构造允许在循环执行之前第一次声明和赋值迭代器(这使得迭代器作用于for(;;)并且隐含在方法中,使得它成为& #34;安全&#34)。我同意for(;;)成语在语法上更清晰,并且在最低执行级别范围内,完全在for(;;)循环内。

答案8是正确的,因为迭代器是在方法内部分配和使用的。

但是,仅仅为了讨论,使用for(;;)语句的以下方法在语法上是正确的,&#34;安全&#34;并从范围和参考角度进行非修改:

在Class定义中的某个地方 ......

while()

类构造函数中的某个地方

ArrayList<String> messageList;

添加方法......

messageList = new ArrayList<String>();