2014-01-30 47 views
1

嗨,感謝您的閱讀!我目前正在學習Java中的泛型,這正是我想要實現的:刪除ArrayList中的重複元素Java

我需要從ArrayList中刪除重複的元素。目前,ArrayList包含整數。我想先打印原始列表,然後在刪除重複項目後打印結果列表。這是我迄今爲止所擁有的。任何幫助表示讚賞!

public static void main(String[] args) { 
    ArrayList<Integer> list1 = new ArrayList<Integer>(); 

    list1.add(1); 
    list1.add(1); 
    list1.add(1); 

    list1.add(2); 
    list1.add(2); 
    list1.add(2); 

    list1.add(3); 
    list1.add(3); 
    list1.add(3); 

    removeDuplicates(list1); 

     System.out.println("Original List with Duplicates: \n" + list1); 
     System.out.println(); 
     //System.out.println("After removing duplicates: \n" + list2); 

} 

public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){ 


    for(int i = 0; i < list2.size(); i++){ 

    //logic to remove duplicates  


    } 

    return list2; 
} 
+1

您是否需要維護列表的順序?如果是這樣,你想保留第一個,最後一個還是其他特定的重複? –

+0

我想最終的結果只是「1 2 3」而不是「1 1 1 2 2 2 3 3 3」。但是,只要重複項目沒有了,順序就不一定重要。 – user3254957

回答

1

第一步

轉換列表的一組。

Set<Integer> aSet = new HashSet<Integer>(list);

第二步

將您重新設置爲一個列表。

list = new ArrayList<Integer>(new HashSet<Integer>(list));

爲什麼它的工作原理

集只能包含獨特的元素。

+0

我不太確定HashSet是什麼。有沒有辦法做到這一點? – user3254957

+0

@ user3254957 HashSet是一個非常有效的Set。一組是一系列獨特的項目。 – Rainbolt

+0

哦,好吧,很高興知道!謝謝! – user3254957

2

您可以將元素添加到Set集合。如果你想保持順序,你應該使用LinkedHashSet

0

將ArrayList轉換爲Set,也許HashSet,然後返回到一個ArrayList,你可以排序,如果你想要的數字順序(集合中的順序通常不能保證) 。

HashSet hs<Integer> = new HashSet(list1); 

ArrayList<Integer> uniqueList = Collections.sort(new ArrayList<Integer>(hs)); 

還有各種SortedSet,其中TreeSet

此外,您還可以使用不易出錯for環路建設:

for (int i : uniqueList) { 
    System.out.println(i); 
} 
+0

ArrayList沒有排序方法 – MadProgrammer

+0

你是對的,用Collections.sort()更新它。 – claj

0
public static void main(String[] args) { 
    ArrayList<Integer> list1 = new ArrayList<Integer>(); 
    ArrayList<Integer> list2 = new ArrayList<Integer>(); 

    list1.add(1); 
    list1.add(1); 
    list1.add(1); 

    list1.add(2); 
    list1.add(2); 
    list1.add(2); 

    list1.add(3); 
    list1.add(3); 
    list1.add(3); 



     System.out.println("Original List with Duplicates: \n" + list1); 
     System.out.println(); 

     list2 = removeDuplicates(list1); 

     System.out.println("After removing duplicates: \n" + list2); 

} 

public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){ 

    ArrayList<E> usedList = new ArrayList<E>(); 
    ArrayList<E> newList = new ArrayList<E>(); 

    for(int i = 0; i < list2.size(); i++){ 

     E object = list2.get(i); 

     if(! usedList.contains(object)) 
     { 
      usedList.add(object); 
      newList.add(object); 
     } 
    } 

    return newList; 
} 

輸出(如預期):

Original List with Duplicates: 
[1, 1, 1, 2, 2, 2, 3, 3, 3] 

After removing duplicates: 
[1, 2, 3] 

如果要與其他類型的工作(而不是java標準,如int),那麼您必須重寫equals方法,因爲它在ArrayListcontains方法中使用。

+0

這在理論上是正確的,但慢得令人無法接受(複雜度n^2)。該算法在實踐中變得太慢以至於無法使用,因爲它必須通過元素經歷新的列表元素以知道新項目是否是唯一的。 – claj

+0

@claj是的,你是對的。但我認爲,爲了學習的目的(效率通常並不那麼重要),這可能是最好的方式。 –

+0

教人們在現實生活中不起作用的東西是相當邪惡的,至少不是沒有說明真的很清楚。你的例子錯過了這種警告。此外,該示例比其他解決方案長得多。 – claj

0
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){ 
    LinkedHashSet<E> dataSet = new LinkedHashSet<E>(list2.size()); 
    dataSet.addAll(list2); 
    ArrayList<E> uniqueLists = new ArrayList<E>(dataSet.size()); 
    uniqueLists.addAll(dataSet); 
    return uniqueLists; 
} 
0

到目前爲止所有其他答案都會創建一個新列表。如果你想修改列表,你可以遍歷列表,同時使用輔助工具Set來跟蹤已經看到的所有元素。要刪除任何List下面的工作(不只是ArrayList),允許元素:

public static <E> List<E> removeDuplicates(List<E> list){ 
    ListIterator<E> iter = list.listIterator(); 
    Set<E> seen = new HashSet<>(); 
    while (iter.hasNext()) { 
     if (!seen.add(iter.next())) { 
      // element not added--must have already been seen, so remove element 
      iter.remove(); 
     } 
    } 
    return list; 
} 

另一種方法是轉儲整個列表爲Set,清除列表,然後添加組的所有元素回到列表中。根據Set的實施情況,這可能會或可能不會保持順序。

public static <E> List<E> removeDuplicates(List<E> list){ 
    Set<E> unique = new LinkedHashSet<>(list); 
    list.clear(); 
    list.addAll(unique); 
    return list; 
} 

編輯:如果(根據您的評論)要完全刪除不唯一下手的元素,你可以修改的第一種方法:

public static <E> List<E> removeNonUnique(List<E> list){ 
    Set<E> seen = new HashSet<>(); // all values seen 
    Set<E> dups = new HashSet<>(); // all values seen more than once 
    for (E elt : list) { 
     if (!seen.add(elt)) { 
      // element not added--must have already been seen, so add to dups 
      dups.add(elt); 
     } 
    } 
    // clean out the list 
    list.removeAll(dups); 
    return list; 
} 

注意,因爲我們是在循環中不修改列表,我們不需要有明確的迭代器。

+0

非常感謝!如果我想刪除所有包含重複元素的內容,該怎麼辦?例如:如果我將4和5作爲單獨元素添加到列表中,則在刪除所有重複元素後,輸出將僅爲「4 5」,因爲1,2和3都具有重複的元素。 – user3254957

+0

@ user3254957 - 我添加了一些代碼來說明我會如何做到這一點。我改變了方法名稱,因爲它實際上並不完全一樣。 –

+0

謝謝泰德!看起來不錯。 – user3254957