那里有没有重复的List实现吗?

Yuv*_*val 80 java collections list duplicates

我知道SortedSet,但在我的情况下,我需要一些实现List,而不是Set.那么在API或其他地方是否有实现?

实现自己应该不难,但我想为什么不先问问这里的人呢?

Cal*_*lum 85

标准库中没有Java集合来执行此操作.但是,LinkedHashSet<E>保存顺序与a类似List,所以如果你将你的集合包装在一个List你想要使用它的时候List你会得到你想要的语义.

或者,Commons Collections(或者commons-collections4,对于通用版本)有一个List你想要的东西:SetUniqueList/ SetUniqueList<E>.

  • @skaffman:他实际上并不是一个白痴,但有时候他会做出......好吧,奇怪的动作.无论如何,我不会在产品中引入错误.在今天的市场上,如果你理解我的观点,我对自己的工作感到满意,并不打算砸门和烧桥. (19认同)
  • Commons课程正是我所需要的,但我的老板告诉我最终自己实施.反正10倍! (5认同)
  • 好吧,没有什么能像重新发明一样!无论如何,你现在都知道是否需要再次出现.馆藏15是一个非常有用的东西; MultiMaps尤其可以减轻人们最终实现自我的痛苦. (5认同)
  • 当SetUniqueList没有参数化类型时,我很惊讶. (3认同)
  • 将 LinkedHashSet 包装在列表中并不能让在列表上实现所有基于索引的操作变得容易或高效。我认为这不是一个合理的做法。而且,有理由不引入公共事物,例如,在尺寸很重要的移动平台上。 (2认同)
  • 杰弗里:在移动平台上,系统通常会删除未使用的类,但可以肯定的是,有很多原因可能不会导致这些"正常"解决方案失败.总是需要做出一些权衡,没有解决方案可以解决所有情况. (2认同)

小智 12

这是我做的,它的工作原理.

假设我有一个ArrayList工作,我做的第一件事是创建一个新的LinkedHashMap.

LinkedHashSet<E> hashSet = new LinkedHashSet<E>()
Run Code Online (Sandbox Code Playgroud)

然后我尝试将我的新元素添加到LinkedHashSet.LinkedHasSet如果新元素是重复的,则add方法不会更改并返回false.所以这成为我可以在添加之前测试的条件ArrayList.

if (hashSet.add(E)) arrayList.add(E);
Run Code Online (Sandbox Code Playgroud)

这是一种简单而优雅的方法,可以防止重复项添加到数组列表中.如果你愿意,你可以将它封装在一个扩展的类中的add方法中ArrayList.只需记住addAll通过循环遍历元素并调用add方法来处理.

  • 是的,我认为,这是最好的解决方案,您也可以简单地使用普通的 HashSet,而不是 Linked,然后您可以根据需要使用您的列表,您还可以决定在某些情况下做什么,例如在特定索引之前的列表中添加元素,您可以决定是否要将重复项移动到此位置。 (2认同)

Yuv*_*val 11

所以这就是我最终做的.我希望这有助于其他人.

class NoDuplicatesList<E> extends LinkedList<E> {
    @Override
    public boolean add(E e) {
        if (this.contains(e)) {
            return false;
        }
        else {
            return super.add(e);
        }
    }

    @Override
    public boolean addAll(Collection<? extends E> collection) {
        Collection<E> copy = new LinkedList<E>(collection);
        copy.removeAll(this);
        return super.addAll(copy);
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> collection) {
        Collection<E> copy = new LinkedList<E>(collection);
        copy.removeAll(this);
        return super.addAll(index, copy);
    }

    @Override
    public void add(int index, E element) {
        if (this.contains(element)) {
            return;
        }
        else {
            super.add(index, element);
        }
    }
}   
Run Code Online (Sandbox Code Playgroud)

  • 注意 - LinkedList.contains()需要扫描整个列表以确定列表中是否包含对象.这意味着当您将对象添加到大型List时,将扫描整个List以进行每个添加操作(在最坏的情况下).这最终可能会变慢. (9认同)
  • 此外,您的addAll覆盖不会检查传递给addAll()的集合中的重复项. (7认同)

Dan*_*ler 5

为什么不用列表封装一个集合,就像这样:

new ArrayList( new LinkedHashSet() )
Run Code Online (Sandbox Code Playgroud)

这为真正的Collections大师留下了另一个实现;-)

  • 这会将集合复制到列表,但是您没有任何已知的排序。但这就是问题的全部。 (4认同)
  • 此构造函数将Set的内容复制到新List中,而不是将其包装。 (2认同)

mat*_*t b 5

你应该认真考虑迪勒的回答:

  1. 不必担心将对象添加到无重复列表中,而是将它们添加到 Set (任何实现)中,这会自然地过滤掉重复项。
  2. 当您需要调用需要 List 的方法时,请将其包装在 a new ArrayList(set)(或 anew LinkedList(set)等)中。

我认为您发布的解决方案存在NoDuplicatesList一些问题,主要是contains()方法方面的问题,而且您的类不处理传递给您的addAll()方法的集合中的重复项检查。