HashMap扩容大小为什么是2的幂

理想的状况,hashMap的存取就是O(1),也就是直接根据hashcode就可以找到它,每个bucket只存储一个节点,链表指向都是null,这样就比较开心了,不要出现一个链表很长的情况。

所以我们希望它能分布的均匀一点,如果让我们设计的话,我们肯定是直接对长度取模-----hashcode % length,但HashMap的设计者却不是这样写的,它写成了2进制运算,如下:

 static final int hash(Object key) {
     int h;
     return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
 }

数组的具体存取规则是tab[(n-1) & hash],其中tab为node数组,n为数组的长度,hash为key的hash值。

为什么设计成(n - 1) & hash 这样呢?在 n 为 2次幂的情况下时,(n - 1) & hash ≈ hash % n ,因为2进制的运算速度远远高于取模,所以就使用了这种方式,所以要求为2的幂。

我们可以看到它求hash的过程,将32位的hashCode值向左移动16位,高位补0,也就是只要了高16位,这是为什么呢?因为hashcode的计算方法导致哈希值的差异主要在高位,而 (n - 1) & hash是忽略了容量以上的高位的,所以 使用h >>>16就是为了避免类似情况的哈希冲突。

posted @ 2019-11-24 17:46  gaopengpy  阅读(1089)  评论(0编辑  收藏  举报