什么样的List <! - ? - >会自动消除重复

时间:2010-09-24 07:24:54

标签: java

什么类型的List会在添加时自动消除重复项。

e.g。对于List,如果我添加1,2,3,4,5,1,2,3 = List应该只包含1,2,3,4,5

10 个答案:

答案 0 :(得分:18)

答案 1 :(得分:16)

Set会自动消除重复项,但它是Collection而不是List。

我认为没有一个List可以消除标准库中的重复项。

Java 6 SE API文档的Annotated Outline of the Collections Framework页面说“通常允许重复。”

答案 2 :(得分:6)

如果您想消除重复项,请使用Set

答案 3 :(得分:4)

如上面的海报所说,没有独特处理的清单。

查看List (Java Platform SE 6)

  

与集合不同,列表通常允许重复元素。更正式地,列表通常允许元素对e1和e2成为e1.equals(e2),并且如果它们根本允许空元素,则它们通常允许多个空元素。有人可能希望通过在用户尝试插入时抛出运行时异常来实现禁止重复的列表,这是不可想象的,但我们希望这种用法很少见。

答案 4 :(得分: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。

答案 5 :(得分:3)

你想要一个Set,例如HashSet(),而不是List?没有列表将消除重复,根据定义列表允许它们。

答案 6 :(得分:2)

不要像有人建议的那样,实现自己的List,它会重复检查,如果add()中有重复,则返回false。

为什么呢?因为您将违反List接口合同,其中包含:

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

List.add(E e)务必返回true并将元素添加到列表中,或抛出异常。列表并不意味着具有重复检查,这就是集合的用途。

答案 7 :(得分:1)

当时你可以自己上课,@Override为你的班级添加方法。 &#34;只看我的代码并练习它&#34;

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);

    }
}

答案 8 :(得分: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){}
};

答案 9 :(得分:0)

获取已排序且没有重复项的实际List的最简单方法是将其包装为:

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

请注意,当您添加到此列表时,重复项将被删除,但这可能适合您。