2016-03-21 135 views
-3

我有一個與ping相關的Arraylist,這些是鏈接到名稱的日期,我想刪除名稱的所有重複項並保留名稱的最近日期。ArrayList重複刪除

代碼

private ArrayList <String> deleteDuplicates() { 
    ArrayList <Ping> tempPings = new ArrayList <Ping>(); 
    tempPings.addAll(jaws.pastMonth()); 
    for (int i = 0; i < tempPings.size(); i++) { 
    Ping tempPing = tempPings.get(i); 
    for (int j = i + 1; j < tempPings.size() - 1; j++) { 
     Ping tempPing2 = tempPings.get(j); 
     if (tempPing.getName().equals(tempPing2.getName())) { 
     if (changePingToDate(tempPing2).before(changePingToDate(tempPing))) { 
      tempPings.remove(j); 
     } 
     } 
    } 
    } 
    return pingToNames(tempPings); 
} 

changePingToDate()是將日期字符串轉換成公曆的方法。

當我使用這段代碼時,它刪除了大部分重複項,但是每次循環中仍有一些剩餘項。我也嘗試過,沒有比較日期和仍然是同樣的問題。誰能幫忙?

感謝您的幫助!

+0

@aribeiro嗨,我已經檢查了答案,它並沒有幫助我的問題,我的.equals似乎工作正常,名稱是完全相同的,例如「瑪麗李」多次,它似乎選擇選擇刪除哪些。 –

+1

您正在調用'.remove()',它可以修改列表的大小和**您正在查看的索引**。你正在跳過價值。 –

+2

使用迭代器。爲了這個原因,我不想在這裏添加另一個答案。 SO和Google都有大量的資源可用。 –

回答

0

不要在列表內部循環時從列表中刪除元素。因此,將要刪除的所有項目添加到另一個列表中,最後從tempPings中刪除所有項目。

private ArrayList <String> deleteDuplicates() { 
    ArrayList <Ping> tempPings = new ArrayList <Ping>(); 
    tempPings.addAll(jaws.pastMonth()); 

    ArrayList <Ping> pingsToRemove = new ArrayList <Ping>(); 
    for (int i = 0; i < tempPings.size(); i++) { 
    Ping tempPing = tempPings.get(i); 
    for (int j = i + 1; j < tempPings.size() - 1; j++) { 
     Ping tempPing2 = tempPings.get(j); 
     if (tempPing.getName().equals(tempPing2.getName())) { 
     if (changePingToDate(tempPing2).before(changePingToDate(tempPing))) { 

      pingsToRemove.add(tempPings.get(j)); 

     } 
     } 
    } 
    } 

    tempPings.removeAll(pingsToRemove); 
    return pingToNames(tempPings); 
} 
+0

你可以使用'Iterator.remove' –

+0

我已經試過這種方式,它結束了,我的400個奇數大小的數組中,9060個元素刪除,不知道爲什麼發生這種情況,如果我要使用迭代器會需要使用兩個?我從來沒有見過並用迭代器迭代迭代器來迭代已經檢查過的元素(對於j = i + 1的情況),這可能嗎?謝謝。 –

+0

嘗試在'pingsToRemove.add(tempPings.get(j));'前檢查'tempPings.get(j)'是否已經添加了if語句。像'if(!pingsToRemove.contains(tempPings.get(j)))'。 – rdonuk

-1

你並不需要「-1」的位置:

for (int j = i + 1; j < tempPings.size() - 1; j++) { 

這將導致你從來沒有在列表中的最後一項進行比較。 j < tempPings.size()足以防止超過數組的末尾。

0

由於您在理解爲什麼remove()操作正在導致問題的問題。我會盡力解釋。

這是一個概括性的解釋,給出你的代碼中的問題的想法。

我有一桶10件東西。在每次迭代中,我都會檢查以確保我正在檢查,直到bucket.size()。如果我刪除i的項目,則i+1的項目將取代它。刪除過程確保bucket.size()現在等於9,而不是10.循環將我的i增加1。跳過i+1處的元素,現在處於i

+0

非常感謝你,非常感謝你! –

+0

@ B.KLewis [This post](http://stackoverflow.com/questions/12196762/delete-duplicates-in-java-arraylist)和[this post](http://www.rgagnon.com/javadetails/ java-remove-duplicates-in-a-list.html)展示了使用迭代器完成這件事情的很好的方法。 –

1
ArrayList<String> values = new ArrayLiist<>(Arrays.asList(
     "apple", 
     "banana", 
     "grape", 
     "banana", 
     "apple", 
     "banana", 
     "apple", 
     "grape" 
)); 

使用Java 8?

values = values.stream().distinct().collect(Collectors.toCollection(ArrayList::new)); 

只有Java 7?

values = new ArrayList<>(new LinkedHashSet<>(values)); 

輸出兩個是

[apple, banana, grape] 

然後,只需在列表上正常人一樣做你的約會操作循環。

+0

這將是非常有用的,不幸的是,我們仍然需要比較日期,併爲每個ping命名留下獨特的名稱,也是最接近的時間。不過謝謝,未來可以看到這非常方便! –

+0

刪除重複項後,只需遍歷列表即可。 –

+0

@ cricket_007流與LinkedHashSet的第二種方式有什麼優勢? –