2013-02-17 60 views
0

我想刪除ArrayList中與第一個元素重複的所有元素,但我希望第一個元素保留在ArrayList中。我試圖用for循環來做到這一點,但它並沒有刪除所有重複項。刪除ArrayList中第一個元素的所有發行版

for(int i = 1; i < arraylist.size(); i++) { 
    if(arraylist.get(i) == v1) 
     arraylist.remove(i); 
} 

v1等於arraylist的第一個元素。 我也試過用的ListIterator,但它去掉了第一個元素

ListIterator<Integer> iterator = arraylist.listIterator(); 
while(iterator.hasNext()) { 
    if(iterator.next().intValue() == v1) 
    iterator.remove(); 
} 

你能幫幫我嗎?

+1

元素編號起始於0(等你INT我應該開始有太多)。 – 2013-02-17 19:34:19

+3

如果他正在迭代刪除所有與第一個元素重複的元素,則不需要它,因爲第一個元素永遠不會是實際的重複元素。我想他的v1變量設置爲arraylist.get(0)。 – 2013-02-17 19:35:25

+0

@JeffLaJoie:非常好的一點,沒有想到這一點。 – 2013-02-17 19:37:48

回答

1

計數(不起來):

Object v1 = arraylist.get(0); 
for (int i = arraylist.size() - 1; i > 1; i--) { 
    if (arraylist.get(i).equals(v1)) 
     arraylist.remove(i); 
} 

你要倒計時因爲當你刪除元素,他們其餘的洗牌下來。

另外,您應該將==更改爲.equals()(如圖所示)。

1

您正在通過使用Iterator及其方法remove執行正確的操作。但是你應該在循環本身之前添加一個next()的調用,以便遍歷第一個元素並且不刪除它。

ListIterator<Integer> iterator = arraylist.listIterator(); 
iterator.next(); // pass the first element. 
while(iterator.hasNext()) { 
    if(iterator.next().intValue() == v1) 
    iterator.remove(); 
} 

相反,別人怎麼說,你不必使用「等於」如果V1是int,這似乎是這樣。

+0

如果第一個代碼不起作用,我懷疑'v1'是一個'Integer',而不是'int'。但是你的代碼將會工作,因爲它會被取消裝箱。 – assylias 2013-02-17 19:41:51

3

您需要單獨閱讀的第一要素,在while loop外,並將其存儲在某個變量,與您會比較的元素的其餘部分,刪除:

ListIterator<Integer> iterator = arraylist.listIterator(); 
int first = 0; 
// Check if there is a first element 
if (iterator.hasNext()) { 
    first = iterator.next(); 

    // Iterate over the rest of the elements 
    while(iterator.hasNext()) { 
     // If this value is equal to `first`, remove it 
     if(iterator.next().intValue() == first) { 
      iterator.remove(); 
     } 
    } 
} 
System.out.println(arrayList); 

iterator.next()將返回一個值類型爲Integer。使用intValue()將會給你的原始值值。

但是由於我正在做一個int基元本身的比較,您根本不需要撥打intValue()。比較之前,您的Integer將自動變爲拆箱至原始int。所以,用下面的一個替換,而if聲明也將工作:

if(iterator.next() == first) { 
    iterator.remove(); 
} 

至於你的第一種方式而言,我會說,一定要使用Iterator,如果你想修改你List正在循環。這將防止你面對尷尬ConcurrentModificationException


參見:

+0

+1 - 但是你可能想添加一些關於自動裝箱的信息,以及爲什麼你要使用'iterator.next()。intValue()'(和'int'首先),因爲在他的例子中他正在比較參考值。 – 2013-02-17 19:40:12

+1

@BrianRoach。當然。添加了一些解釋:) – 2013-02-17 19:44:18

0
int v1 = arraylist.get(0); 
for(int i = 0; i < arraylist.size(); i++) { 
    if(arraylist.get(i) == v1){ 
     arraylist.remove(i); 
     i--; 
    } 
} 

如果你不想使用迭代的方法:其他的答案是正確的,你需要從零開始的索引(如果你想刪除第一個),但是你也需要遞減迭代變量(每次從列表中刪除一個元素,因爲您正在使用remove()更改列表的長度。

0

在迭代它的同時,最好小心地從數組(或迭代列表)中移除元素。

根據我的經驗,最簡單的方法是創建一個新列表。你能考慮這樣做嗎?看看你的代碼,首先記住在「==」上使用「equals」進行比較(因爲.equals的意思是「有意義的等價」,我認爲這是你在這裏需要的)。 (編輯:可能無所謂這裏由於自動裝箱,但它仍然是一個很好的習慣,有)

但即使這樣也不能正常工作:

for (int i = 1; i < arraylist.size(); i++) { 
    if (arraylist.get(i).equals(v1)) 
     arraylist.remove(i); 
} 

既然想象你有三個整數一個ArrayList,所有一樣。當i == 1時,索引1處的元素與索引0處的值進行比較,並將其刪除。但是,索引2處的元素變爲索引1處的元素,for循環計數器增加,從而「丟失」刪除列表中的最後一個條目。

我可以推薦這樣的東西嗎?

List<Integer> newlist = new ArrayList<Integer>(); 
newlist.add(v1); 
for (Integer integer : arraylist) { 
    if (!integer.equals(v1)) 
     newlist.add(integer); 
} 

祝你好運!

P.S.如果你覺得勇敢,你也許可以做一個整潔的一行出這一點: CollectionUtils.filter(Collection,Predicate)

CollectionUtils.filter(arraylist.subList(1, arraylist.size()), new Predicate() { 
    @Override 
    public boolean evaluate(Object o) { 
     return !v1.equals(o); 
    } 
}); 
相關問題