java集合框架与HashSet输出

Collection与Map

java集合框架与HashSet输出java集合框架与HashSet输出
备注:
  • 图中只列出了主要容器,仍有一部分容器没有列出
  • 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

参考链接: