是否有一个保留订单的Set也实现了List?


84

我试图找到的实现java.util.List,并java.util.Set在Java中的同一时间。我希望此类仅允许唯一元素(如Set)并保留其顺序(如List)。JDK 6中是否存在?

List<T>#add(int, T)一点很重要,这样我就可以插入特定位置。


您是要保留其插入顺序还是由a定义的某些顺序Comparator?您还需要List接口的语义吗?

Answers:


207

TreeSet按元素顺序排序;LinkedHashSet保留插入顺序。希望其中之一就是您所追求的。

您已经指定要插入任意位置,我怀疑您必须编写自己的-只需创建一个包含aHashSet<T>和an的类即可ArrayList<T>。在添加项目时,在将其添加到列表之前,请检查它是否在集合中。

另外,Apache的commons-collections4提供ListOrderedSetSetUniqueList,它们的行为类似,应该满足给定的要求。



12

你是说喜欢LinkedHashSet吗?这样可以保留输入顺序,但不允许重复。

恕我直言,这是一个不寻常的要求,但是您可以编写一个没有重复的列表。

class SetList<T> extends ArrayList<T> {
    @Override
    public boolean add(T t) {
        return !super.contains(t) && super.add(t);
    }

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

    @Override
    public boolean addAll(Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            added |= add(t);
        return added;
    }

    @Override
    public boolean addAll(int index, Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            if (!super.contains(t)) {
                super.add(index++, t);
                added = true;
            }
        return added;
    }
}

它没有实现List接口,请参见我对问题的更改
yegor256

2
stackoverflow.com/a/8185105/253468看起来更好,因为它没有O(n)插入复杂性,必须在双重存储和O(log(n))插入操作之间进行权衡。
TWiStErRob

8

您不能立即实施ListSet而不能违反合同。例如,参见Set.hashCode合同:

集合的哈希码定义为集合中元素的哈希码之和,其中空元素的哈希码定义为零。

另一方面,以下是合同List.hashCode

列表的哈希码定义为以下计算的结果:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

因此,不可能实现保证两个合同均得到履行的单一类别。equals实施同样的问题。



0

我遇到了类似的问题,所以我写了自己的问题。看这里。该IndexedArraySet扩展ArrayList和工具Set,所以它应该支持所有你需要的操作。请注意,ArrayList对于大列表,将元素插入到中间的位置可能会很慢,因为以下所有元素都需要移动。我IndexedArraySet没有改变。


0

另一个选项(减去List接口要求)是Guava的ImmutableSet,它可以保留插入顺序。从他们的维基页面

除排序的集合外,订单从构建时开始保留。例如,

ImmutableSet.of("a", "b", "c", "a", "d", "b")

将按照“ a”,“ b”,“ c”,“ d”的顺序遍历其元素。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.