是否有一个保留订单的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提供ListOrderedSet和SetUniqueList,它们的行为类似,应该满足给定的要求。



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

您不能立即实施List,Set而不能违反合同。例如,参见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.