【发布时间】:2020-07-15 13:28:46
【问题描述】:
我正在向某人展示我的代码,他们说这会导致未定义的行为。作为一名 Java 程序员,这不是我所理解的。在下面的代码块中,我将遍历 scenes,它是一个 ArrayList,并从中删除元素。
for(int i = 0; i < scenes.size() - 1; i++)
{
if(!(Double.valueOf(scenes.get(i + 1)) - Double.valueOf(scenes.get(i)) > 10))
{
scenes.remove(i + 1);
i--;
}
}
这会编译并且不会在运行时抛出异常,但我仍然不确定它是否是编程禁忌,为什么它是编程禁忌,以及正确的做法是什么。我听说过使用 Iterator.remove() 以及创建一个全新的 List。
【问题讨论】:
-
这里有几样东西要解压。首先,链表的基于索引的访问需要
O(i)时间,因为要到达特定索引,您必须从其头部(或尾部,以最接近的一个,假设它具有此优化)开始遍历每个节点。一般来说,迭代列表的更好方法是使用它的Iterator,因为它会根据内部实现以最佳方式实现。 -
然后,当您使用
Iterator时,它会在您修改列表后抛出ConcurrentModificationException- 修改后,在修改之前创建的大多数迭代器会变得陈旧并抛出异常,如果您在那种状态下使用它们。Iterator.remove()不会使该特定迭代器过时,但会使所有其他迭代器过时。 -
@jnorman,这是关于 python 的问题,不一定是 Java。
标签: java list iterator concurrentmodification