[英]Ordering of elements in Java HashSet
Why do the second and third sets preserve order: 为什么第二组和第三组保留顺序:
Integer[] j = new Integer[]{3,4,5,6,7,8,9};
LinkedHashSet<Integer> i = new LinkedHashSet<Integer>();
Collections.addAll(i,j);
System.out.println(i);
HashSet<Integer> hi = new HashSet<Integer>(i);
System.out.println(hi);
LinkedHashSet<Integer> o = new LinkedHashSet<Integer>(hi);
System.out.println(o);
Here's the output I get: 这是我得到的输出:
3,4,5,6,7,8,9
3,4,5,6,7,8,9
3,4,5,6,7,8,9
The second one (just using HashSet
) is only a coincidence. 第二个(只使用
HashSet
)只是巧合。 From the JavaDocs : 来自JavaDocs :
This class implements the Set interface, backed by a hash table (actually a HashMap instance).
此类实现Set接口,由哈希表(实际上是HashMap实例)支持。 It makes no guarantees as to the iteration order of the set;
它不能保证集合的迭代顺序; in particular, it does not guarantee that the order will remain constant over time .
特别是,它不保证订单会随着时间的推移保持不变 。 This class permits the null element.
该类允许null元素。
The third one ( LinkedHashSet
) is designed to be like that: 第三个(
LinkedHashSet
) 设计如下:
Hash table and linked list implementation of the Set interface, with predictable iteration order.
Set接口的哈希表和链表实现,具有可预测的迭代顺序。 This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries.
此实现与HashSet的不同之处在于它维护了一个贯穿其所有条目的双向链表。 This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order).
此链接列表定义迭代排序,即元素插入集合(插入顺序)的顺序。 Note that insertion order is not affected if an element is re-inserted into the set.
请注意,如果将元素重新插入到集合中,则不会影响插入顺序。 (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)
(如果s.contains(e)在调用之前立即返回true,则调用s.add(e)时,将元素e重新插入到集合中。)
@Behrang's answer is good but to be more specific, the only reason why the HashSet
seems to be in the same order as the LinkedHashSet
is that integer.hashCode()
happens to be the integer value itself so the numbers happen to be in order in the HashSet
internal storage. @Bhhrang的答案很好,但更具体地说,
HashSet
看起来与LinkedHashSet
顺序相同的唯一原因是integer.hashCode()
碰巧是整数值本身,所以数字恰好按顺序排列HashSet
内部存储。 This is highly implementation specific and as @Behrang says, really a coincidence. 这是高度具体的实现,正如@Behrang所说,真的是巧合。
For example, if you use new HashSet<>(4)
which sets the initial number of buckets to be 4 (instead of 16) then you might have gotten the following output: 例如,如果您使用
new HashSet<>(4)
将桶的初始数量设置为4(而不是16),那么您可能获得了以下输出:
HashSet<Integer> hi = new HashSet<Integer>(4);
...
[3, 4, 5, 6, 7, 8, 9]
[8, 9, 3, 4, 5, 6, 7]
[8, 9, 3, 4, 5, 6, 7]
If you had stuck in values >= 16, you might get something like this: 如果你卡在> = 16的值,你可能会得到这样的东西:
Integer[] j = new Integer[] { 3, 4, 5, 6, 7, 8, 9, 16 };
...
[3, 4, 5, 6, 7, 8, 9, 16]
[16, 3, 4, 5, 6, 7, 8, 9]
[16, 3, 4, 5, 6, 7, 8, 9]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.