簡體   English   中英

遍歷列表時刪除列表的隨機元素

[英]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):

  1. 創建一個HashSet。

  2. 遍歷輸入列表的元素:

    1. 訪問元素並將其添加到集合中(如果應將其刪除)
    2. 訪問元素的鄰居,並將應刪除的任何元素添加到集合中。
  3. 調用list.removeAll(set)

ArrayListremoveAll方法調用內部的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM