有一个保存插入顺序的Set也实现了List吗?

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

List<T>#add(int, T)是很重要的,所以我可以插入到特定的位置。

TreeSet按元素顺序sorting; LinkedHashSet保留广告订单。 希望这些之一是你以后的。

你已经指定了你想要插入到任意位置,我怀疑你必须自己写 – 只要创build一个包含HashSet<T>ArrayList<T> ; 当添加一个项目时,在将它添加到列表之前,检查它是否在集合中。

LinkedHashSet是答案。

迭代次序和唯一性。

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

你的意思是像LinkedHashSet ? 这保留了input的顺序,但不允许重复。

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

 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; } } 

您无法一次实现ListSet ,而不会违反合同。 例如,请参阅Set.hashCode合同:

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

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

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

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

所以不可能实现保证双方合同履行的单一类。 equals执行相同的问题。

如果您不想将自己限制为JDK 6,则可以使用Apache常用集合库,它提供了与您的需求完全匹配的ListOrderedSet 。 这就像ListSet在一起:)

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

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

除了sorting的集合, 订单从施工时间保留。 例如,

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

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