2013-10-22 82 views
9

我有一個數組的順序,說List<Integer>139, 127, 127, 139, 130刪除陣列中的重複而不改變元素

如何去除它的重複和保持其順序不變?即139, 127, 130

+0

手動刪除重複項,在這種情況下您可以保留訂單。 – 2013-10-22 07:39:42

回答

15

使用java.util.LinkedHashSet的實例。

Set<Integer> set = new LinkedHashSet<>(list); 
+1

Humm ...這是降級,我正在使用Java 7的菱形符號。 –

+3

對不起,在我的咖啡後,我將成爲一個完全不同的人。 – Maroun

3

從你的清單建設Set - 「不包含重複元素的集合」:

Set<Integer> yourSet = new HashSet<Integer>(yourList); 

,並將其轉換回任何你想要的。

注意:如果要保留訂單,請改用LinkedHashSet

+0

HashSet是否保留插入順序? –

+1

您必須使用LinkedHashSet來保留插入順序。 – Axel

+0

你需要一個LinkedHashSet – Andreas

0

使用LinkedHashSet刪除重複和維護訂單。

0

正如我不能扣除,你需要保留插入順序,即完成@Maroun Maroun所寫的,使用set,但specialidez實現像LinkedHashSet<E> whitch完全是你需要的東西。

2

利用這種單行:

yourList = new ArrayList<Integer>(new LinkedHashSet<Integer>(yourList)) 
0

迭代通過陣列(通過迭代器,不FOREACH)和刪除重複。使用set來查找重複項。

OR

迭代通過陣列,並加入到LinkedHashSet所有元素,它不允許重複和保持元件的順序。 然後清除數組,遍歷set並將每個元素添加到數組中。

0

雖然ArrayList的轉換到HashSet有效去除重複,如果你需要保留插入順序,我寧願建議你使用這個變體

//列表是字符串

Set<String> s = new LinkedHashSet<String>(list); 
的一些名單

然後,如果您需要取回List引用,則可以再次使用轉換構造函數。

0

有2種方式:

  1. 創建獨特的整數新名單僅

    • (同Maroun Maroun答案)
    • 你可以用2個嵌套維權喜歡做此O(nn/2):

      List<int> src,dst; 
      // src is input list 
      // dst is output list 
      dst.allocate(src.num); // prepare size to avoid slowdowns by reallocations 
      dst.num=0;    // start from empty list 
      for (int i=0;i<src.num;i++) 
      { 
      int e=1; 
      for (int j=0;i<dst.num;i++) 
          if (src[i]==dst[j]) { e=0; break; } 
      if (e) dst.add(src[i]); 
      } 
      
  2. 您可以選擇重複的項目並刪除它們... O(2。N)與被標記刪除

    • 這是方法要快得多,但你需要對整個INT範圍
    • 如果使用數字< 0,10000內存表>,然後它會採取BYTE CNT [10001]
    • 如果你使用數字< -10000,10000>那麼它將需要BYTE cnt [20002]
    • 對於小範圍,這樣可以,但是如果你必須使用32位範圍,則需要4GB!
    • 有位緊縮你可以爲每個價值2位所以這將是隻有1GB但仍然太多對我的口味
    • 確定現在如何檢查口是心非......

      List<WORD> src; // src is input list 
      BYTE cnt[65536]; // count usage for all used numbers 
      int i; 
      for (i=0;i<65536;i++) cnt[i]=0; // clear the count for all numbers 
      for (i=0;i<src.num;i++)   // compute the count for used numbers in the list 
      if (cnt[src[i]]!=255) 
          cnt[src[i]]++; 
      
    • 後這個任意數量的我被複制,如果(CNT [I]> 1)
    • 所以現在我們要刪除重複項(除了一個)
    • 做改變CNT []這樣

      for (i=0;i<65536;i++) if (cnt[i]>1) cnt[i]=1; else cnt[i]=0; 
      
    • OK現在來刪除部分:

      for (i=0;i<src.num;i++)   
      if (cnt[src[i]]==1) cnt[src[i]]=2; // do not delete the first time 
          else if (cnt[src[i]]==2)   // but all the others yes 
          { 
          src.del(i); 
          i--;        // indexes in src changed after delete so recheck for the same index again 
          } 
      
  3. 你可以結合這兩種方法一起

  4. 從列表
  5. 刪除項是因爲在列表
    • 項目移動緩慢但可以通過添加刪除標記來加速項目
    • 而不是刪除只需設置標誌
    • 畢竟要刪除的項目被標記然後只需一次爲O(n)刪除下襬

PS。對不起,非標準列表使用,但我認爲代碼是足夠可理解的,如果不評論我和我回應

PPS。與有符號值一起使用不要忘記將地址移動一半範圍!

0

下面我給出了一個示例示例,它實現了一個通用函數,用於從arraylist中刪除重複項,並同時維護順序。

import java.util.*; 
public class Main { 
    //Generic function to remove duplicates in list and maintain order 
    private static <E> List<E> removeDuplicate(List<E> list) { 
     Set<E> array = new LinkedHashSet<E>(); 
     array.addAll(list); 
     return new ArrayList<>(array); 
    } 
    public static void main(String[] args) { 
     //Print [2, 3, 5, 4] 
     System.out.println(removeDuplicate(Arrays.asList(2,2,3,5, 3, 4))); 
     //Print [AB, BC, CD] 
     System.out.println(removeDuplicate(Arrays.asList("AB","BC","CD","AB"))); 
    } 
}