Java遍历HashSet为什么输出是有序的?

按博主看书上面显示,这段代码的输出应该是无序的,但是博主多次输出都是有序的,于是猜想hashset究竟是有序还是无序?

package xiaowen2;

import java.util.*;

public class SetOfInteger { public static void main(String[] args) {

Random rand = new Random(47);

Set<Integer> intset = new HashSet<Integer>();

for (int i = 0; i < 10000; i++) intset.add(rand.nextInt(30));

System.out.println(intset); } }

刚好在知乎上看到答案于是搬运过来了。

“不保证有序”和“保证无序”不等价,HashSet的iterator是前者而不是后者,所以在一次运行中看到有序的结果也是正常的,但不能依赖这个有序行为。
况且HashSet并不关心key的“排序”,就算其iterator“有序”通常也是说“按元素插入顺序”(LinkedHashSet就支持插入顺序遍历)。
题主插入HashSet的是Integer,其hashCode()实现就返回int值本身。所以在对象hashCode这一步引入了巧合的“按大小排序”。
然后HashMap.hash(Object)获取了对象的hashCode()之后会尝试进一步混淆。
JDK8版java.util.HashMap内的hash算法比JDK7版的混淆程度低;在[0, 2^32-1]范围内经过HashMap.hash()之后还是得到自己。题主的例子正好落入这个范围内。外加load factor正好在此例中让这个HashMap没有hash冲突,这就导致例中元素正好按大小顺序插入在HashMap的开放式哈希表里。

转载自知乎