2015-05-29 156 views
2

我有一個MainList有61個元素和subList的9個元素。 在subList中的9個元素中,其中8個在MainList中。Arraylist循環故障

我的目標是簡單地刪除這兩個列表中存在的對象。

for(int i = 0; i < subList.size();i++){ 
    for(int j = 0; j < mainList.size();j++){ 
     if(subList.get(i).equals(mainList.get(j))){ 
      mainList.remove(j); 
      subList.remove(i); 

      break; 
     } 
    } 
} 

我現在面臨的問題是,在for循環之後,subList仍然5元,這意味着僅for循環能夠找到4個對象相似。

之後,我又寫了for循環調試,如下的情況:

for(int i = 0; i < subList.size();i++){ 
    for(int j = 0; j < mainList.size();j++){ 
    if(subList.get(i).equals(mainList.get(j))){ 
      System.out.println("something"); 
     } 
    } 
} 

而且我能看到的「東西」的4倍。我想知道爲什麼第一個forloop不能找到所有類似的對象?

+2

不要循環使用索引並更改循環內的集合,這很可能會導致錯誤。改用迭代器。 – Thomas

回答

2

放棄循環並使用Collection。 removeAll

移除所有還包含在 指定的集合(可選操作)這個集合的元素。在此呼叫 返回後,此集合將不包含與 指定集合共有的元素。

由於您想從兩個列表中刪除重複項,您需要製作其中一個列表的副本。

List<?> sublistCopy = new ArrayList(sublist); 

subList.removeAll(mainList); 
mainList.removeAll(sublistCopy); 
3

當你從一個ArrayList中刪除一個元素時,它後面的元素索引減1,所以你應該減少你的循環索引來解決這個問題。

例如,subList.remove(3);會將索引4處的元素先前移至索引3,因此爲了讓您的循環不跳過該元素,應該減少循環的索引。

for(int i = 0; i < subList.size();i++){ 
    for(int j = 0; j < mainList.size();j++){ 
     if(subList.get(i).equals(mainList.get(j))){ 
      mainList.remove(j); 
      subList.remove(i); 
      i--; 
      j--; // actually j-- may not be needed, since you break 
       // from the inner loop and start a new inner loop 
      break; 
     } 
    } 
} 
+0

我認爲一個更優雅的選擇是從sublist.size()回退到0.然後你不必減少「手動」索引 –

+1

@Pablo我認爲使用Iterator的remove方法會更加優雅。那麼你根本不用擔心指數。 – Eran

4

爲什麼不使用Collection.removeAll()方法:

mainList.removeAll(subList); 

remove()「從List荷蘭國際集團改變了指數。建議使用Iterator遍歷並從集合中刪除:

for (Iterator<...> iterator = mainList.iterator() ; iterator.hasNext() ;) { 
    Object o = iterator.next(); 
    if (subList.contains(o) ) { iterator.remove(); } 
} 

乾杯,

+0

我想'mainList.removeAll(subList)'將只從mainList中刪除公共對象,而不是從subList – ksap

+0

這是真的。目前尚不清楚OP是否只想移除主要元素或是否存在對稱情況。無論如何,延伸到你描述的情況是微不足道的。關鍵是OP應該使用內置的方法。 –

0

確保兩個元素是相等的(檢查是否有一些白色的空間包含列表)。

for(int i=0;i<subList.size();i++){ 
    if(mainList.contains(subList.get(i)){ 
      mainList.remove(subList.get(i)); //remove the element from mainList. 
      subList.remove(i); //removes the element from subList. 

    } 
} 
0

您不應該使用索引同時修改列表。可以使用一個while循環和iterator

作爲每文檔:

迭代器允許調用者具有良好定義的語義迭代期間移除底層集合的元素。