根据我的阅读,在迭代列表时删除元素是安全的。 (而不是为每个循环使用简单)。
假设我有一个元素列表,我想访问所有元素,但是当我访问每个元素时,我将访问它的邻居(注意我有一个地图,每个元素都会给我它的邻居)因此,我会 必须从原始列表中删除其他元素。因此我无法使用 iterator.remove()。
这样做的好方法是什么,也就是说,从列表中删除元素而不是使用迭代器处于某个位置?
我有一个想法如下,将我的元素放在地图中,值为 一个布尔值,(对于访问为true,否则为false)。 因此,我浏览了我的列表,并且对于每个元素我设置它访问了真,如果一个如果它的邻居我也看到访问该元素时,我也将它们设置为真。
答案 0 :(得分:0)
使用for循环而不是foreach迭代项目。然后根据需要删除。以下是从List
中删除偶数元素的示例import java.util.List;
import java.util.ArrayList;
class Test {
public static void main(String[] args){
final List<Integer> ints = new ArrayList<Integer>();
ints.add(100);
ints.add(1);
ints.add(15);
ints.add(42);
ints.add(187);
System.out.println("Original List");
for(Integer i: ints){
System.out.println(i);
}
/* Remove any even elements from the list */
for(int i=0; i < ints.size(); i++){
if(ints.get(i) % 2 == 0){
ints.remove(i);
}
}
System.out.println("\nModified List");
for(Integer i: ints){
System.out.println(i);
}
}
}
答案 1 :(得分:0)
让我们假设您正在讨论的输入列表是ArrayList
。
以下方法将为您提供O(N)
行为(至少对于OpenJDK Java 6到Java 8):
创建一个HashSet。
迭代输入列表中的元素:
致电list.removeAll(set)
。
removeAll
的{{1}}方法调用内部ArrayList
方法(see here)。此方法对batchRemove
的后备阵列执行单次传递,删除元素并填充孔。它通过调用ArrayList
来测试每个元素以查看是否应该删除它。对于set.contains(elem)
,该测试为HashSet
,因此O(1)
调用为removeAll(set)
,其中O(N)
为列表大小。
有趣的是,N
将是arrayList.removeAll(hashSet)
,其中O(N)
是列表长度,但删除了相同的元素:
N
将是for (Iterator it = arrayList.iterator; it.hasNext(); ) {
if (hashSet.contains(it.next())) {
it.remove();
}
}
,其中O(NM)
是列表长度,N
是设置大小。