美文网首页
HashMap系列 (1)

HashMap系列 (1)

作者: 云敲窗 | 来源:发表于2020-12-03 18:35 被阅读0次

    先看下hash(Object key)方法,详细大家基本都能看懂,但是知道这一步(h = key.hashCode()) ^ (h >>> 16)原因的人很少。

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

    这里主要理解一下 (h = key.hashCode()) ^ (h >>> 16) 这一段代码

    hash 算法的精髓都在这里面

    1.key.hashCode() 获取hash 值,为什么不用hashCode直接比较呢?

    答: 这里就要说一下HashMap 默认为什么是16位 ,hashCode 是int 类型的, int 类型是16位的. <br/>而为什么不用hashCode 直接比较,是因为hashCode 16位,而16位的数字散列的肯定不如32位的二进制散列的均匀,更容易发生hash碰撞所以不用hashCode直接比较
    

    2.从代码中我们可以明显的知道高于16位的通过 ^ (异或) 右移16位来得到比较的值,但是小于16位的呢?

    答: 简单的从上面代码可以得知, 如果是大于16位得到hashCode,然后右移16位,其实比较的也就是从左往右的16位数字. 当时我就有个困惑 小于16位呢?(这也是自己对^异或运算掌握的不够好)其实异或后得到的还是它本身
    
    PS: 下面是对我自己的解释: 
    
    异或运算符(^)
    参加运算的两个数据,按二进制位进行“异或”运算。
    运算规则:0^0=0;  0^1=1;  1^0=1;   1^1=0;
    即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
    
    首先右边运算得到的是32位全为0, 右边是本身,而 1^0=1;的情况还是1 所以得到的结果还是它本身
    

    __3.为什么加载因子是0.75呢?

    答: 其实是通过泊松分布来计算的.在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少扩容rehash操作次数,所以,一般在使用HashMap时建议根据预估值设置初始容量,以便减少扩容操作。
    
    选择0.75作为默认的加载因子,完全是时间和空间成本上寻求的一种折衷选择。
    
    在维基百科中的解释是这样的:
    
    对于开放定址法,加载因子是特别重要因素,应严格限制在0.7-0.8以下。超过0.8,查表时的CPU缓存不命中(cache missing)按照指数曲线上升。因此,一些采用开放定址法的hash库,如Java的系统库限制了加载因子为0.75,超过此值将resize散列表。

    相关文章

      网友评论

          本文标题:HashMap系列 (1)

          本文链接:https://www.haomeiwen.com/subject/zqcvwktx.html