我试图找到的实现java.util.List
,并java.util.Set
在Java中的同一时间。我希望此类仅允许唯一元素(如Set
)并保留其顺序(如List
)。JDK 6中是否存在?
有List<T>#add(int, T)
一点很重要,这样我就可以插入特定位置。
Answers:
TreeSet
按元素顺序排序;LinkedHashSet
保留插入顺序。希望其中之一就是您所追求的。
您已经指定要插入任意位置,我怀疑您必须编写自己的-只需创建一个包含aHashSet<T>
和an的类即可ArrayList<T>
。在添加项目时,在将其添加到列表之前,请检查它是否在集合中。
另外,Apache的commons-collections4提供ListOrderedSet
和SetUniqueList
,它们的行为类似,应该满足给定的要求。
答案是LinkedHashSet。
迭代顺序和唯一性。
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
List
接口,请参见我对问题的更改
你是说喜欢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
接口,请参见我对问题的更改
您不能立即实施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
组合在一起:)
List
接口
另一个选项(减去List
接口要求)是Guava的ImmutableSet
,它可以保留插入顺序。从他们的维基页面:
除排序的集合外,订单从构建时开始保留。例如,
ImmutableSet.of("a", "b", "c", "a", "d", "b")
将按照“ a”,“ b”,“ c”,“ d”的顺序遍历其元素。
Comparator
?您还需要List
接口的语义吗?