Foreach against for(int…) loop - why does foreach raises exceptions when removing elements?
我想知道为什么我不能从列表中删除元素,当我用foreach循环迭代它时,比如:
1 2 3 4 5 6 7 8 |
然后移除这些元素:
1 2 3 |
似乎foreach循环不允许删除循环队列中"仍在"的对象。我说的对吗?
为什么for int循环不关心这个?在这个循环中,我可以轻松地删除仍在循环中的对象。
谢谢
嗯,最初这个问题被标记为"C",现在被删除了。然而。。。。
for/loop不关心是否从集合中移除元素,这不是真的。如果在继续操作时删除元素,则在删除元素后索引元素将出现问题,因为索引不再与下一个元素匹配。只有以相反的顺序循环(从最后一个元素到第一个元素),才能避免for/loop问题。
前臂内部也有同样的问题。枚举器对元素保持一个
例如:
假设一系列"鸟"、"动物"和"鱼"的集合
- 前臂开始时,内部电流为0(指向"鸟")。
- 删除"birds",则"animals"位于索引0(当前仍指向该索引)
- 前进到下一个元素(current=1,指向"fish")。
- 没有例外,下一步将退出循环。
foreach的设计不允许出现这种情况。
就Java而言,答案是在JavaDoc(强调雷)中:
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
至少对于Java来说,您是正确的:问题是用于遍历列表中元素的迭代器不允许修改。它将抛出一个ConcurrentModificationException。引用JavaAPI JavaDoc为JavaUTIL.ARAYLIST
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException. Thus, in the face of concurrent
modification, the iterator fails quickly and cleanly, rather than
risking arbitrary, non-deterministic behavior at an undetermined time
in the future.
另一种方法是使用允许此类修改的迭代器,而不是arraylist的默认值,或者显式创建迭代器,而不是使用foreach循环,并使用它在遍历列表时必须更改内容的方法。
参见Java中Frach循环中的调用移除,一般使用迭代器,如果有更多元素,则与HasNew检查