2
Set<String> stringSet = new HashSet<String>();

明显不会保持秩序

Set<String> linkedHastSet = new LinkedHashSet<String>();

从上面的集合中读取元素时,它应该保持顺序,但有时它不会?我的观察是错的还是我遗漏了什么?

4

3 回答 3

3

只有 LinkedHashSet 保证可预测的顺序

来自 jdoc:

Set接口的哈希表和链表实现,具有可预测的迭代顺序

于 2016-02-25T13:30:58.363 回答
1

JavadocLinkedHashSet相当清楚:

迭代排序...是元素插入集合的顺序(插入顺序)

于 2016-02-25T13:22:21.317 回答
0

并且应该是唯一的

一个Set实现不包含重复的元素,如 Javadoc 中更详细的解释。

java集合保留顺序

“订单”是什么意思?

广告订单:LinkedHashSet

如果您的意思是跟踪对象最初添加到集合中的顺序,请使用LinkedHashSet.

Set< String > colors = new LinkedHashSet<> () ;
String peachPuff = "PeachPuff" ;
colors.add( "CornflowerBlue" ) ;
colors.add( peachPuff ) ;
colors.add( "DarkSlateGray" ) ;
colors.add( peachPuff ) ; // Adding again. Original insertion order maintained.

在 IdeOne.com 上实时运行代码。请注意peachPuff尽管对象被第二次添加到集合中,但它仍然保持在其原始的 #2 位置。

System.out.println( "colors.toString(): " + colors ) ;

colors.toString(): [CornflowerBlue, PeachPuff, DarkSlateGray]

排序顺序:TreeSetConcurrentSkipListSet

如果您的意思是保持元素按其内容排序,请使用NavigableSet(successor to SortedSet) 的实现。

排序是通过以下方式完成的:

与 Java 捆绑的两个类实现NavigableSet(和SortedSet):TreeSet& ConcurrentSkipListSet

TreeSet

如果您在单个线程中操作集合,或者仅使用跨线程的集合进行只读,请使用TreeSet.

例子:

Set< String > names = new TreeSet<> () ;
names.add( "Carol" ) ;
names.add( "Alice" ) ;
names.add( "Bob" ) ;

这将按字母顺序报告。请参阅在 IdeOne.com 上实时运行的代码

names.toString(): [爱丽丝,鲍勃,卡罗尔]

ConcurrentSkipListSet

如果跨线程操作集合,并发性是一个问题。使用ConcurrentSkipListSet类。

您可能想了解跳过列表算法。

枚举定义顺序:EnumSet

如果要按照枚举对象的定义顺序跟踪集合枚举对象(请参阅教程EnumSet),请使用. 这个类针对枚举进行了高度优化,执行速度非常快并且使用的内存非常少。

示例:跟踪DayOfWeek枚举中的周末天数。

Set< DayOfWeek > weekend = EnumSet.of( DayOfWeek.SUNDAY , DayOfWeek.SATURDAY ) ;

尽管我们以错误的顺序定义了集合,但仍将按照枚举EnumSet中定义的顺序迭代项目。DayOfWeek该顺序是周一至周日,因此我们EnumSet将在周日之前迭代周六报告。

请参阅在 IdeOne.com 上实时运行的代码

周末.toString():[星期六,星期日]

于 2020-01-19T02:00:47.247 回答