是否有一个插入顺序保留Set也实现List?

时间:2011-11-18 15:50:57

标签: java collections

我试图在Java中同时找到java.util.Listjava.util.Set的实现。我希望这个类只允许使用唯一元素(如Set)并保留它们的顺序(如List)。它是否存在于JDK 6中?

拥有List<T>#add(int, T)非常重要,因此我可以插入特定位置。

7 个答案:

答案 0 :(得分:200)

TreeSet按元素顺序排序; LinkedHashSet保留了广告订单。希望其中一个就是你所追求的。

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

另外,Apache的commons-collections4提供了ListOrderedSetSetUniqueList,它们的行为相似,应该符合给定的要求。

答案 1 :(得分:30)

LinkedHashSet就是答案。

迭代排序和唯一性。

http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html

答案 2 :(得分:10)

你的意思是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;
    }
}

答案 3 :(得分:6)

如果没有合同违规,您无法一次实施ListSet。例如,请参阅Set.hashCode合同:

  

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

另一方面,这里是List.hashCode的合同:

  

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

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

因此,实施单一类别无法保证两份合同得以履行是不可能的。 equals实施的问题相同。

答案 4 :(得分:4)

如果您不限制自己使用JDK 6,则可以使用Apache common collections库,它可以满足您的需求 - ListOrderedSet。这就像ListSet结合在一起:))

答案 5 :(得分:0)

我有类似的问题,所以我写了自己的问题。见hereIndexedArraySet扩展ArrayList并实现Set,因此它应该支持您需要的所有操作。请注意,将元素插入ArrayList中间的位置对于大型列表来说可能会很慢,因为需要移动以下所有元素。我的IndexedArraySet不会改变这一点。

答案 6 :(得分:0)

另一个选项(减去List接口要求)是Guava的ImmutableSet,它保留了插入顺序。来自their wiki page

  

除了已排序的集合,订单会从施工时间开始保留。例如,

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

将以“a”,“b”,“c”,“d”的顺序迭代其元素。