Java Set 是否保留顺序?一个方法正在向我返回一个 Set,据说数据是有序的,但在 Set 上迭代时,数据是无序的。有没有更好的方法来管理这个?是否需要更改方法以返回 Set 以外的内容?
13 回答
该Set
接口不提供任何排序保证。
它的子接口SortedSet
表示一个根据某些标准排序的集合。在 Java 6 中,有两个标准容器实现了SortedSet
. 它们是TreeSet
和ConcurrentSkipListSet
。
除了SortedSet
接口,还有LinkedHashSet
类。它记住元素插入集合的顺序,并按该顺序返回其元素。
LinkedHashSet是您所需要的。
正如许多成员建议的那样,使用LinkedHashSet来保留集合的顺序。你可以使用这个实现来包装你的集合。
SortedSet实现可用于排序顺序,但出于您的目的使用LinkedHashSet。
同样来自文档,
“这种实现将其客户从 HashSet 提供的未指定的、通常混乱的排序中解脱出来,而不会增加与 TreeSet 相关的成本。它可用于生成与原始集合具有相同顺序的集合的副本,而不管原始集合如何集合的实现:"
来源:http ://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
Set只是一个接口。为了保持顺序,您必须使用该接口和子接口 SortedSet 的特定实现,例如 TreeSet 或 LinkedHashSet。你可以用这种方式包装你的 Set:
Set myOrderedSet = new LinkedHashSet(mySet);
要保留订单,请使用List
或LinkedHashSet
.
Set
以下是Java 中可用的标准实现的顺序特征的快速总结:
- 保持插入顺序:LinkedHashSet和CopyOnWriteArraySet(线程安全)
- 保持项目在集合内排序:TreeSet、EnumSet(特定于枚举)和ConcurrentSkipListSet(线程安全)
- 不按任何特定顺序保留项目:HashSet(您尝试过的那个)
对于您的具体情况,您可以先对项目进行排序,然后使用 1 或 2 中的任何一个(最有可能是LinkedHashSet
或TreeSet
)。或者更有效地,您可以将未排序的数据添加到 aTreeSet
中,它将自动为您处理排序。
LinkedHashSet 是 HashSet 的有序版本,它在所有元素中维护一个双向链表。当您关心迭代顺序时,请使用此类而不是 HashSet。
从 javadoc 为Set.iterator()
:
返回此集合中元素的迭代器。返回的元素没有特定的顺序(除非这个集合是某个提供保证的类的实例)。
而且,正如shuuchan已经说过的, aTreeSet
是一个Set
具有保证顺序的实现:
元素使用它们的自然顺序或在集合创建时提供的 Comparator 进行排序,具体取决于使用的构造函数。
通常set是不保持顺序的,比如HashSet是为了快速找到一个元素,但是你可以试试LinkedHashSet它会保持你输入的顺序。
有2个不同的东西。
- 对集合中的元素进行排序。我们有 SortedSet 和类似的实现。
- 保持一组中的插入顺序。可以使用 LinkedHashSet 和 CopyOnWriteArraySet(线程安全)。
Set 接口本身并没有规定任何特定的顺序。然而,SortedSet确实如此。
Set 返回的迭代器不应该以有序的方式返回数据。看到这两个 java.util.Iterators 到同一个集合:它们是否必须以相同的顺序返回元素?
只能SortedSet
下单Set