2010-08-26 47 views
12

我有一個ArrayList,其中包括我想要刪除的項目數。我有要刪除項目的ID存儲在另一個列表中。想通下面的代碼應該平凡的工作,但由於某種原因,刪除()調用返回錯誤值:爲什麼我的ArrayList.remove(id)調用不起作用?

ArrayList<Integer> toRemove = new ArrayList<Integer>(); 
    ArrayList<JCheckBox> al = new ArrayList<JCheckBox>(); 

    /* Code that adds a bunch of items to al, and a few integers to toRemove */ 

    System.out.println("Size before removing: " + al.size()); 
    for (int i = toRemove.size() - 1; i >= 0; i--) { 
    System.out.println("Removing id: " + toRemove.get(i) + ": "); 
    System.out.println(al.get(toRemove.get(i))); 
    System.out.println(al.remove(toRemove.get(i))); 
    } 
    System.out.println("Size after removing: " + al.size()); 

我會得到它如果get()調用也返回了一個錯誤的值,但它確實返回有問題的對象。我在這裏錯過了什麼?

上述代碼的輸出:

Size before removing: 3 
Removing id: 2: 
javax.swing.JCheckBox[...] 
false 
Size after removing: 3 
+0

你能張貼'al'和'toRemove'的確切聲明嗎? – 2010-08-26 22:20:29

+0

發佈了所需的定義。 – zigdon 2010-08-26 22:49:56

回答

31

我的猜測是您有一個事實,即remove()超載既intObject,而get()只需要一個int問題。嘗試remove(toRemove.get(i).intValue())

remove(Object)AbstractCollection將通過列表中搜索並刪除指定的對象,這不會在那裏,因爲你是在發送一個Integer和列表只有JCheckBox秒。您正在嘗試撥打remove(int),但因爲您要給它一個Integer,所以調用Object超載。通過將Integer轉換爲int,可以避免此問題

另外,您是否始終可以確定toRemove中的Id總是等於索引?如果去除不是最小的,它不會是最小的。

+0

謝謝 - 工作!是的,當我構建移除時,我確信它是按順序排列的,所以當我以相反的順序瀏覽它時,我不需要在元素被移除時調整索引。 – zigdon 2010-08-26 22:32:49

+0

這個答案不考慮'NULL'對象 – Salman 2015-11-19 06:39:28

+0

@Salman這個問題意味着沒有'null'。如果存在'null',那麼remove()'調用上方的行將拋出一個空指針,同時將參數拆箱到外部'get()'調用。 – ILMTitan 2015-11-19 10:06:22

1

您的代碼有兩個問題。首先,調用錯誤的「toRemove」方法。當你調用「toRemove.get(i)」時,返回值被自動裝入到java.lang.Integer中,而不是int。因此,調用java.util.List#remove(Object)而不是java.util.List#remove(int)。它試圖移除一個Integer對象,並返回false。 如果將整數轉換爲int,則將調用所需的方法。

第二個問題:每次刪除列表中的一個元素時,所有後續元素的索引都會隨着這些元素「向下移動」而改變。有幾種方法可以解決這個問題。一種是按降序對索引列表進行排序。另一種方法是使用一組索引,創建一個新數組,並將僅索引不在集合中的那些元素複製到新數組中。