zoukankan      html  css  js  c++  java
  • hashmap 为什么初始化容量是2的幂次方

    个人理解 做下记录,不正确的地方望不吝赐教

    这是hashmap初始化容量时候 对容量大小做的处理,保证初始化容量为最近的2的幂次方(JDK1.8)

      static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
    

    思考,为啥非得是2的幂次方 ,2的倍数不行么,奇数不行么?

      结合源码加别人的资料,做如下解释:
       1.奇数不行的解释很能被接受,在计算hash的时候,确定落在数组的位置的时候,计算方法是(n - 1) & hash ,奇数n-1为偶数,偶数2进制的结尾都是0,经过&运算末尾都是0,会 
          增加hash冲突。
       2.为啥要是2的幂,不能是2的倍数么,比如6,10?
           2.1 hashmap 结构是数组,每个数组里面的结构是node(链表或红黑树),正常情况下,如果你想放数据到不同的位置,肯定会想到取余数确定放在那个数据里,  计算公式: 
                 hash % n,这个是十进制计算。在计算机中,  (n - 1) & hash,当n为2次幂时,会满足一个公式:(n - 1) & hash = hash % n,计算更加高效。
           2.2 只有是2的幂数的数字经过n-1之后,二进制肯定是  ...11111111  这样的格式,这种格式计算的位置的时候,完全是由产生的hash值类决定,而不受n-1(组数长度) 影响。你可能会想,
                受影响不是更好么,又计算了一下,类似于扰动函数,hash冲突可能更低了,这里要考虑到扩容了,2的幂次方*2,在二进制中比如4和8,代表2的2次方和3次方,他们的2进制结构相 似,比如
                4和8   00000100    0000 1000   只是高位向前移了一位,这样扩容的时候,只需要判断高位hash,移动到之前位置的倍数就可以了,免去了重新计算位置的运算。
  • 相关阅读:
    shell 中"${b2}" and "${b:2}"
    关于 libpcap的安装
    ubuntu adsl 上网
    2011.1.18 运算符优先级
    Tail Queues
    fd_set struct
    读取和修改操作array 配置文件的方法
    smarty调试方法
    一个CURL例子
    cakephp数据库事务transactions
  • 原文地址:https://www.cnblogs.com/jinjian91/p/11917413.html
Copyright © 2011-2022 走看看