205

Java Set 是否保留顺序?一个方法正在向我返回一个 Set,据说数据是​​有序的,但在 Set 上迭代时,数据是无序的。有没有更好的方法来管理这个?是否需要更改方法以返回 Set 以外的内容?

4

13 回答 13

298

Set接口不提供任何排序​​保证。

它的子接口SortedSet表示一个根据某些标准排序的集合。在 Java 6 中,有两个标准容器实现了SortedSet. 它们是TreeSetConcurrentSkipListSet

除了SortedSet接口,还有LinkedHashSet类。它记住元素插入集合的顺序,并按该顺序返回其元素。

于 2012-05-25T10:30:12.337 回答
123

LinkedHashSet是您所需要的。

于 2012-05-25T10:29:20.463 回答
19

正如许多成员建议的那样,使用LinkedHashSet来保留集合的顺序。你可以使用这个实现来包装你的集合。

SortedSet实现可用于排序顺序,但出于您的目的使用LinkedHashSet

同样来自文档,

“这种实现将其客户从 HashSet 提供的未指定的、通常混乱的排序中解脱出来,而不会增加与 TreeSet 相关的成本。它可用于生成与原始集合具有相同顺序的集合的副本,而不管原始集合如何集合的实现:"

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

于 2012-12-07T07:30:30.057 回答
12

Set只是一个接口。为了保持顺序,您必须使用该接口和子接口 SortedSet 的特定实现,例如 TreeSet 或 LinkedHashSet。你可以用这种方式包装你的 Set:

Set myOrderedSet = new LinkedHashSet(mySet);
于 2012-05-25T10:29:45.257 回答
8

要保留订单,请使用ListLinkedHashSet.

于 2012-05-25T10:31:04.067 回答
7

Set以下是Java 中可用的标准实现的顺序特征的快速总结:

  1. 保持插入顺序:LinkedHashSetCopyOnWriteArraySet(线程安全)
  2. 保持项目在集合内排序:TreeSetEnumSet(特定于枚举)和ConcurrentSkipListSet(线程安全)
  3. 不按任何特定顺序保留项目:HashSet(您尝试过的那个)

对于您的具体情况,您可以先对项目进行排序,然后使用 1 或 2 中的任何一个(最有可能是LinkedHashSetTreeSet)。或者更有效地,您可以将未排序的数据添加到 aTreeSet中,它将自动为您处理排序。

于 2012-05-25T10:36:00.710 回答
6

LinkedHashSet 是 HashSet 的有序版本,它在所有元素中维护一个双向链表。当您关心迭代顺序时,请使用此类而不是 HashSet。

于 2018-04-04T11:58:12.350 回答
3

从 javadoc 为Set.iterator()

返回此集合中元素的迭代器。返回的元素没有特定的顺序(除非这个集合是某个提供保证的类的实例)。

而且,正如shuuchan已经说过的, aTreeSet是一个Set具有保证顺序的实现:

元素使用它们的自然顺序或在集合创建时提供的 Comparator 进行排序,具体取决于使用的构造函数。

于 2012-05-25T10:30:11.440 回答
3

通常set是不保持顺序的,比如HashSet是为了快速找到一个元素,但是你可以试试LinkedHashSet它会保持你输入的顺序。

于 2012-05-25T10:30:44.253 回答
1

有2个不同的东西。

  1. 对集合中的元素进行排序。我们有 SortedSet 和类似的实现。
  2. 保持一组中的插入顺序。可以使用 LinkedHashSet 和 CopyOnWriteArraySet(线程安全)。
于 2019-10-02T15:44:18.663 回答
0

Set 接口本身并没有规定任何特定的顺序。然而,SortedSet确实如此。

于 2012-05-25T10:30:58.030 回答
0

Set 返回的迭代器不应该以有序的方式返回数据。看到这两个 java.util.Iterators 到同一个集合:它们是否必须以相同的顺序返回元素?

于 2012-05-25T10:31:46.750 回答
-2

只能SortedSet下单Set

于 2012-05-25T10:33:15.340 回答