我遇到了这段代码,它在迭代时从列表中删除了项目,但它并没有抛出并发异常并在列表中留下了一些项目。这是为什么?例子:。public class Application { public static void main(String[] args) { List<Integer> integerList = new ArrayList<Integer>(); integerList.add(1); integerList.add(2); for (Integer integer : integerList) { removeInteger(integerList, integer); } System.out.println(integerList.toString()); // prints [2] as it was not removed (while it should be) } private static void removeInteger(List<Integer> integerList, Integer integer) { for (Integer integer1 : integerList) { if (integer.equals(integer1)) { int index = integerList.indexOf(integer); if (index >= 0) { integerList.remove(index); } } } }}如果我将removeInteger方法更改为 useIterator而不是main我传递的副本,则integerList一切都按预期工作。
1 回答
holdtom
TA贡献1805条经验 获得超10个赞
首先,如果您向列表中添加更多元素,它仍然会失败并显示ConcurrentModificationException.
由于发布的示例没有失败,我们必须看看内部发生了什么。
如果您进行调试,您会在发布的示例中看到,两个循环仅迭代一次。删除内部循环(方法)中的元素removeInteger
会耗尽两个迭代器。由于没有进一步的交互,因此不会导致错误。“仅”修改后的调用Iterator#next
可能导致 ConcurrentModificationException。
是的,但为什么它会耗尽它们呢?
查看源代码ArrayList#Itr
我们可以看到
public boolean hasNext() { return cursor != size; }
只检查一个名为 的变量size
。此变量size
是 的属性ArrayList
。当remove
被调用时,该变量递减。因此,下次hasNext
调用时,迭代器假定不再有新元素。
旁注:cursor
指向列表中的下一个元素。
添加回答
举报
0/150
提交
取消