java集合框架与HashSet输出
Collection与Map
- 图中只列出了主要容器,仍有一部分容器没有列出
- EnumSet为抽象类,RegularEnumSet与JumboEnumSet是它仅有的两个子类
- Collections下的 checked 容器、synchronized 容器与 unmodifiable 容器没有列出。Map下还有WeakHashMap子类没有列出。
HashSet 有序输出问题
看下面一个例子,猜一下它的输出:
public class IteratorTest {
public static void main(String[] args) {
Random rand = new Random(47);
Set<Integer> intSet = new HashSet<>();
for (int i = 0; i < 10000; i++) {
intSet.add(rand.nextInt(30));
}
for (Integer num : intSet) {
System.out.print(num + " ");
}
}
}
输出结果(基于JDK8):
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
你可能会说,这不是有序的吗?
事实上,对于HashSet,Iterator不保证有序,这和保证无序是有区别的。对于LinkedHashSet,支持按插入顺序遍历;对于TreeSet,支持按二叉树遍历。
对于这个例子来说,在不同版本的JDK版本中输出可能结果有所不同。HashSet内部采用HashMap来存储,在 jdk 8 中,hash算法有了一些改变,因此才见到了有序的结果。
对上面的例子做一下修改:
public class IteratorTest {
public static void main(String[] args) {
Random rand = new Random(47);
Set<Integer> intSet = new HashSet<>();
for (int i = 0; i < 10000; i++) {
intSet.add(rand.nextInt(30) + (1 << 16));
}
for (Integer num : intSet) {
System.out.print(num - (1 << 16) + " ");
}
}
}
输出结果(基于JDK8):
1 0 3 2 5 4 7 6 9 8 11 10 13 12 15 14 17 16 19 18 21 20 23 22 25 24 27 26 29 28
参考链接: