2010-09-24 44 views

回答

17

看一看LinkedHashSet

+1

LinkedHashSet是Set接口的一個實現......爲什麼你推薦這個而不是另一個? – pgras 2010-09-24 07:35:17

+5

@pgras,可能是因爲添加元素的順序保持完整,就像列表一樣。 – 2010-09-24 07:37:05

+2

@Wolfgang,@Bart K - 問題是LinkedHashSet不是一個List。它實現了Set API,並且不允許您在位置上獲取,更新或插入或刪除元素。 – 2010-09-24 07:46:29

15

Set將自動消除重複,但它是一個集合,而不是一個列表。

我不認爲有一個清單,消除標準庫中的重複。

Java 6 SE API文檔的Annotated Outline of the Collections Framework頁面指出「通常允許重複」。

+1

+1指出集合和Lits之間的區別。 – 2013-08-16 11:00:13

5

如果你想消除重複,使用Set

3

你想要一個集也許,例如HashSet(),而不是一個List?沒有列表將消除重複,按照定義列表允許它們。

4

就像上面的海報說的那樣,沒有List with Unique處理。

List (Java Platform SE 6)

set不同,列表通常允許重複的元素。更正式地說,列表通常允許元素e1和e2的對,使得e1.equals(e2),並且它們通常允許多個null元素(如果它們完全允許空元素的話)。有人可能希望通過在用戶嘗試插入時拋出運行時異常來實現禁止重複的列表,這並不是不可想象的,但我們預計這種用法很少見。

+0

稀有...和昂貴。拋出異常很昂貴。 – 2010-09-24 09:42:33

+0

昂貴,真實。但有時不可避免。許多收集方法拋出UnsupportedOperationException,並且客戶端代碼沒有辦法找到它們提前做的事情。 RuntimeExceptions是你必須在集合框架中處理的東西。 – 2010-09-24 16:18:51

4

您可以擴展現有的java.util.ArrayList並封裝其中的java.util.Set。你應該覆蓋所有add(...)addAll(...)remove方法與第一次檢查,如果一個元素是封裝組(的情況下將其添加到列表中的):

public class ListSet<E> extends ArrayList<E> { 

    private Set<E> set; 

    public ListSet() { 
     set = new HashSet<E>(); 
    } 

    @Override 
    public boolean add(E element) { 
     if(set.add(element)) { 
      super.add(element); 
      return true; 
     } 
     return false; 
    } 

    // other add and remove methods 
} 

編輯

由於@Alnitak提到:不要忘記在刪除元素時同步備份HashSet。

+1

我喜歡這個,這就是我會如何做到的。這特別保留了列表的所有語義,同時強制執行無重複約束(儘管以某些內存爲代價)。附:不要忘記同步你的支持HashSet每當一個元素被刪除... – Alnitak 2010-09-24 10:17:27

+0

我正在考慮做一些非常相似的事情,但我掛在你身上會執行add(index,E)實現。我想如果你在數據中發現了E的重複,那麼你在這個位置插入失敗。列表接口爲add(index,E)返回void,所以你不能報告這個失敗的條件。 – 2013-01-11 16:55:09

0

這裏是ArrayList中的擴展,它不允許重複:

public class NoDupeList<E> extends ArrayList<E>{ 

    private static final long serialVersionUID = -2682691450003022201L; 

    public NoDupeList(){ 
     super(); 
    } 

    public NoDupeList(final Collection<? extends E> c){ 
     super(c instanceof Set<?> ? c : new LinkedHashSet<E>(c)); 
    } 

    public NoDupeList(final int initialCapacity){ 
     super(initialCapacity); 
    } 

    @Override 
    public boolean add(final E e){ 
     return !this.contains(e) && super.add(e); 
    }; 

    @Override 
    public boolean addAll(final Collection<? extends E> c){ 
     final List<E> intermediate = new ArrayList<E>(c); 
     intermediate.removeAll(this); 
     return super.addAll(intermediate); 
    } 

    @Override 
    public void add(final int index, final E element){ 
     if(!this.contains(element)){ 
      super.add(index, element); 
     } 
    }; 

    @Override 
    public E set(final int index, final E element){ 
     if(this.contains(element) && !this.get(index).equals(element)){ 
      throw new IllegalArgumentException("This would cause a duplicate"); 
     } 
     return super.set(index, element); 
    }; 

} 

我不能處理的唯一事情是set()方法。我的解決方案是拋出一個IllegalArgumentException如果這會導致重複,但也許應該通常讓這個方法拋出一個UnsupportedOperationException來代替。

總之,這裏的測試方法:

@Test 
public void testNoDupeList() throws Exception{ 
    final List<String> list = 
     new NoDupeList<String>(Arrays.asList("abc", "def", "abc")); 
    assertEquals(list, Arrays.asList("abc", "def")); 
    list.addAll(Arrays.asList("abc", "def", "ghi")); 
    assertEquals(list, Arrays.asList("abc", "def", "ghi")); 
    try{ 
     list.set(2, "abc"); 
     fail("This should have caused an Exception"); 
    } catch(final Exception e){} 
}; 
2

不要像有人建議,實現自己的名單,做重複檢查,如果在添加重複返回false()。

爲什麼?因爲你將打破List接口合同,說:

public boolean add(E e) 
[...] 
Returns: 
     true (as specified by Collections.add()) 

List.add(E E)必須返回true和元素添加到列表中,或拋出異常。列表並不意味着有重複的檢查,這是什麼集合。

0

來獲取排序並沒有重複將它包像這樣的實際List最簡單的方法:

List<Integer> unique = 
    new ArrayList<Integer>(new TreeSet<Integer>(Arrays.asList(1, 1, 2, 2, 3, 3))); 

注意,當您添加到這個列表重複將雖然被淘汰,但也許這對你有用。

1

當時你可以讓自己的班級和@Override添加方法到你的班級。 「只看我的代碼並練習它」

import java.util.ArrayList; 

import java.util.List; 

class MyList extends ArrayList<Integer> { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public boolean add(Integer element) { 

     if (!found(element)) { 
      super.add(element); 
     } 
     return false; 

    } 
    public boolean found(Integer e) { 
     return equals(e); 
    } 
    public boolean equals(Integer e) { 

     for (int i = 0; i < super.size(); i++) { 
      if (super.get(i).equals(e)) 
       return true; 
     } 

     return false; 
    } 

} 

public class ListRemovingDuplicated { 

    public static void main(String[] abd) { 

     List<Integer> obj = new MyList(); 
     obj.add(10); 
     obj.add(20); 
     obj.add(10); 
     obj.add(10); 
     obj.add(30); 
     System.out.println(obj); 

    } 
} 
相關問題