有一个保存插入顺序的Set也实现了List吗?
我试图在Java中同时findjava.util.List
和java.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; } }
您无法一次实现List
和Set
,而不会违反合同。 例如,请参阅Set.hashCode
合同:
集合的哈希码被定义为集合中元素的哈希码的总和,其中空元素的哈希码被定义为零。
另一方面这里是List.hashCode
的合约:
列表的哈希码被定义为以下计算的结果:
int hashCode = 1; for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
所以不可能实现保证双方合同履行的单一类。 equals
执行相同的问题。
如果您不想将自己限制为JDK 6,则可以使用Apache常用集合库,它提供了与您的需求完全匹配的ListOrderedSet 。 这就像List
和Set
在一起:)
我有类似的问题,所以我写了我自己的。 看到这里 。 IndexedArraySet
扩展ArrayList
并实现Set
,所以它应该支持所有你需要的操作。 请注意,将元素插入到ArrayList
中间的位置对于大列表来说可能会很慢,因为以下所有元素都需要移动。 我的IndexedArraySet
不会改变这一点。
另一个选项(减去List
接口要求)是Guava的ImmutableSet
,它保留了插入顺序。 从他们的wiki页面 :
除了sorting的集合, 订单从施工时间保留。 例如,
ImmutableSet.of("a", "b", "c", "a", "d", "b")
将按照“a”,“b”,“c”,“d”的顺序遍历其元素。