列表在Java中使用for循环迭代时从ArrayList或LinkedList中删除元素?若然,原因为何?
我向某人展示我的代码,他们说这会导致未定义的行为。作为一名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
# 1 楼答案
在
ArrayList
中,从列表中间删除一个元素需要将索引较高的所有元素下移一。如果你只做一次(或几次)就可以了,但如果你重复做的话效率会很低你也不想用
Iterator
来解决这个问题,因为Iterator.remove()
也有同样的问题更好的方法是浏览列表,将想要保留的元素移动到新位置;然后去掉列表末尾的部分:
(这种“移位并清除”的方法是
ArrayList.removeIf
所使用的方法;这里不能直接使用这种方法,因为不能检查列表中的相邻元素,只能访问当前元素)您可以采用类似的方法,该方法也可以有效地处理非随机访问列表,例如
LinkedList
。您需要避免重复调用get
和set
,因为在LinkedList
的情况下,它们是O(size)
在这种情况下,可以使用
ListIterator
而不是普通索引:或者类似的。我还没有测试过它,而且
ListIterator
使用起来总是很混乱# 2 楼答案
这很简单,适用于ArrayList或LinkedList: