为什么 Iterator.next() 会抛出 ConcurrentModificationException
奇怪的是,这一小段代码抛出了上面提到的异常。 另外,看看网上发布的代码,这似乎是正确的:
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());
}
}
}
有什么建议吗? 谢谢
Strangly enough, this small piece of code throws the above mentioned Exception.
Also, looking at code posted around the web this seems to be correct:
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());
}
}
}
Any advice?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
此调用:
应该在您完成对 ArrayList 的所有写入之后。
因此,在您的代码中,在开始迭代之前执行此操作,如下所示:
This call:
should be after you've done all the writes into your ArrayList.
So in your code do this just before you start iterating like this:
这是因为您修改了通过
iterator()
获取 Iterator 和调用next()
之间的支持列表。迭代器的典型用法是:
或者更好的是,使用新的 for-each 循环:
确保在循环外部对 Collection 执行添加操作。
It's because you've modified the backing list between getting the Iterator via
iterator()
and callingnext()
.The typical usage of an Iterator is:
Or better yet, use the new for-each loop:
Make sure to to perform additions to the Collection outside of the loop.
您在实例化对象
IteratorTest
时定义了Iterator
。然后将一些数据添加到ArrayList
,arr
。您现在已经修改了列表,因此
Iterator
的状态无效。如果不使用
Iterator
来执行此操作,则无法使用Iterator
来更改ArrayList
。You are defining the
Iterator
upon instantiation of your object,IteratorTest
. You then add some data to theArrayList
,arr
.You have now modified your list, and thus the
Iterator
's state is invalid.You cannot use the
Iterator
and change theArrayList
without using theIterator
to do it.答案 4 在技术上是正确的,但这并不是因为使用了
for(;;)
或“foreach”循环而不是while()
循环。这只是迭代器在类中声明的范围而不是方法的问题。首先,让我们看一下hasNext()
和next()
这两个方法的行为:hasNext()
方法只是查询内部游标(指数);next()
实际上使光标前进,因此这是可能引发异常的“修改”。如果您尝试使用在使用next()
的方法之外声明和分配的迭代器,则代码将在第一个next()
上引发异常,无论它是for(;;)
还是while()
。在答案 4 和 8 中,迭代器是在方法内本地声明和使用的。碰巧的是,由于
for(;;)
构造允许在循环执行之前首次声明和分配迭代器(这使得迭代器的作用域为for(;; )
并隐式地在方法中,使其“安全”)。我同意 for(;;) 习惯用法在语法上更清晰,并且将范围限制在最低执行级别,完全在 for(;;) 循环内。答案 8 是正确的,因为迭代器是在方法内部本地分配和使用的。
但是,为了便于讨论,以下使用
while()
语句的方法在语法上是正确的、“安全的”并且从范围和引用的角度来看是不可修改的:在类定义中的某处
...
在类构造函数的某处
添加一个方法...
Answer 4 is technically correct, but not because a
for(;;)
or "for each" loop is used instead of awhile()
loop. It simply a matter of the Iterator's declared scope within the Class rather than the method. First, let's look at the behavior of the two methodshasNext()
andnext()
:The
hasNext()
method simply queries an internal cursor (index);next()
actually advances the cursor, therefore that is the "modification" that could raise the exception. If you try to use an Iterator declared and assigned outside of the method in whichnext()
is being used, the code will throw an exception on the firstnext()
, regardless if it's afor(;;)
orwhile()
.In Answer 4 and 8, the iterator is declared and consumed locally within the method. It just so happens that since the
for(;;)
construct allows for a first time declaration and assignment of the iterator before the loop executes (which makes the iterator scoped to thefor(;;)
and implicitly within the method, making it "safe"). I agree that thefor(;;)
idiom is cleaner syntactically and fences scope at the lowest level of execution, completely within thefor(;;)
loop.Answer 8 is correct, because the Iterator is assigned and used locally inside the method.
But, just for sake of the discussion, the following method using a
while()
statement is syntactically correct, "safe" and non-modifying from a scope and reference perspective:somewhere in the Class definition
...
somewhere in the class constructor
add a method...