2010-09-24 40 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); 

    } 
} 
相关问题