我试图在Java中同时找到java.util.List
和java.util.Set
的实现。我希望这个类只允许使用唯一元素(如Set
)并保留它们的顺序(如List
)。它是否存在于JDK 6中?
拥有List<T>#add(int, T)
非常重要,因此我可以插入特定位置。
答案 0 :(得分:200)
TreeSet
按元素顺序排序; LinkedHashSet
保留了广告订单。希望其中一个就是你所追求的。
您已指定希望能够在任意位置插入,我怀疑您必须自己编写 - 只需创建一个包含HashSet<T>
的类, ArrayList<T>
;添加项目时,在将其添加到列表之前检查它是否在集合中。
另外,Apache的commons-collections4提供了ListOrderedSet
和SetUniqueList
,它们的行为相似,应该符合给定的要求。
答案 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)
如果没有合同违规,您无法一次实施List
和Set
。例如,请参阅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。这就像List
和Set
结合在一起:))
答案 5 :(得分:0)
我有类似的问题,所以我写了自己的问题。见here。 IndexedArraySet
扩展ArrayList
并实现Set
,因此它应该支持您需要的所有操作。请注意,将元素插入ArrayList
中间的位置对于大型列表来说可能会很慢,因为需要移动以下所有元素。我的IndexedArraySet
不会改变这一点。
答案 6 :(得分:0)
另一个选项(减去List
接口要求)是Guava的ImmutableSet
,它保留了插入顺序。来自their wiki page:
除了已排序的集合,订单会从施工时间开始保留。例如,
ImmutableSet.of("a", "b", "c", "a", "d", "b")
将以“a”,“b”,“c”,“d”的顺序迭代其元素。