[英]Deleting random elements of a list while going through the list
根據我的閱讀,在遍歷列表時刪除元素是安全的。 (而不是對每個循環使用簡單方法)。
假設我有一個元素列表,並且想訪問所有元素,但是當我訪問每個元素時,我將訪問它的鄰居(請注意,我為每個元素都有一張地圖,這將給我它的鄰居),因此我將不得不從原始列表中刪除其他元素。 因此,我不能使用iterator.remove()。
什么是執行此操作的好方法,也就是說,從我要遍歷的列表中刪除元素而不將其置於迭代器的位置?
我的一個想法是,將我的元素放在一個映射中,其值作為布爾值(對於true表示訪問,否則為False)。 因此,我瀏覽了列表,並為每個元素設置了它訪問的正確性,如果在訪問該元素時也看到了它的鄰居,我也將其設置為true。
使用for循環而不是foreach來遍歷項目。 然后根據需要將其卸下。 這是從列表中刪除偶數元素的示例
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);
}
}
}
讓我們假設您正在談論的是ArrayList
的輸入列表。
以下方法將為您提供O(N)
行為(至少對於OpenJDK Java 6到Java 8):
創建一個HashSet。
遍歷輸入列表的元素:
調用list.removeAll(set)
。
ArrayList
的removeAll
方法調用內部的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
為列表長度, M
為設置的大小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.