Set<String> stringSet = new HashSet<String>();
明显不会保持秩序
Set<String> linkedHastSet = new LinkedHashSet<String>();
从上面的集合中读取元素时,它应该保持顺序,但有时它不会?我的观察是错的还是我遗漏了什么?
Set<String> stringSet = new HashSet<String>();
明显不会保持秩序
Set<String> linkedHastSet = new LinkedHashSet<String>();
从上面的集合中读取元素时,它应该保持顺序,但有时它不会?我的观察是错的还是我遗漏了什么?
只有 LinkedHashSet 保证可预测的顺序
来自 jdoc:
Set接口的哈希表和链表实现,具有可预测的迭代顺序
JavadocLinkedHashSet
相当清楚:
迭代排序...是元素插入集合的顺序(插入顺序)
并且应该是唯一的
一个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]
TreeSet
或ConcurrentSkipListSet
如果您的意思是保持元素按其内容排序,请使用NavigableSet
(successor to SortedSet
) 的实现。
排序是通过以下方式完成的:
compareTo
在任何对象实现Comparable
接口上调用定义。Comparator
您传递的实现。与 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
将在周日之前迭代周六报告。
周末.toString():[星期六,星期日]