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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3784985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:21:35  来源:igfitidea点击:

What kind of List<?> will automatically eliminate duplicates

java

提问by user339108

What kind of List will automatically eliminate duplicates when they are added.

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

e.g. for a List if I add 1,2,3,4,5,1,2,3 = the List should just contain just 1,2,3,4,5

例如对于列表,如果我添加 1,2,3,4,5,1,2,3 = 列表应该只包含 1,2,3,4,5

回答by Wolfgang

Have a look at LinkedHashSet

看看LinkedHashSet

回答by richj

A Set will automatically eliminate duplicates, but it is a Collection rather than a List.

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

I don't think there is a List that eliminates duplicates in the standard library.

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

The Annotated Outline of the Collections Frameworkpage of the Java 6 SE API documentation says that "Duplicates are generally permitted."

集合框架的注释大纲在Java SE 6 API文档的页说:“重复一般都是允许的。”

回答by Nivas

If you want to eliminate duplicates, use Set

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

回答by boecko

Like the above poster said, there is no List with Unique handling.

就像上面的海报说的那样,没有具有唯一处理的列表。

Look at List (Java Platform SE 6)

查看列表(Java Platform SE 6)

Unlike sets, lists typically allow duplicate elements. More formally, lists typically allow pairs of elements e1 and e2 such that e1.equals(e2), and they typically allow multiple null elements if they allow null elements at all. It is not inconceivable that someone might wish to implement a list that prohibits duplicates, by throwing runtime exceptions when the user attempts to insert them, but we expect this usage to be rare.

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

回答by Bart Kiers

You could extend the existing java.util.ArrayListand encapsulate a java.util.Setin it. You should override all add(...), addAll(...)and removemethods and first check if an element is in the encapsulated set (in the case of adding it to the list):

您可以扩展现有java.util.ArrayList并将 a 封装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
}

EDIT

编辑

As @Alnitak mentioned: don't forget to sync your backing HashSet whenever an element is removed.

正如@Alnitak 提到的:不要忘记在删除元素时同步您的支持 HashSet。

回答by Brian

You want a Set maybe, e.g. HashSet(), rather than a List? No List will eliminate duplicates, by definition Lists permit them.

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

回答by user2688803

Do not, like someone suggested, implement your own List that does duplicate check and returns false if there is a duplicate at add().

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

Why? Because you will BREAK the List interface contract which says:

为什么?因为您将打破 List 接口合同,其中说:

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

List.add(E e) MUST return true and add the element to the list, or throw an exception. Lists are not meant to have duplicate checks, that is what Sets are for.

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

回答by Srinivas Nellore

At the time you can make your own class and @Overrideadd method to your class. "just see my code and practice it"

那时您可以创建自己的类并向类中@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);

    }
}

回答by Fabian Steeg

The easiest way to get an actual Listthat is sorted and has no duplicates would be to wrap it like this:

获得List已排序且没有重复的实际值的最简单方法是将其包装如下:

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

Note that when you add to this list duplicates will notbe eliminated though, but maybe this works for you.

请注意,当您添加到此列表时,不会消除重复项,但也许这对您有用。

回答by Sean Patrick Floyd

Here is an extension of ArrayList that rejects duplicates:

这是拒绝重复的 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);
    };

}

The only thing I can't deal with is the set()method. My solution is to throw an IllegalArgumentExceptionif that would cause a duplicate, but perhaps one should generally let this method throw an UnsupportedOperationExceptioninstead.

我唯一无法处理的是set()方法。我的解决方案是抛出一个IllegalArgumentExceptionif 这会导致重复,但也许通常应该让这个方法抛出一个UnsupportedOperationException

Anyway, here's a test method:

无论如何,这是一个测试方法:

@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){}
};