HashMap将值映射到哈希数组上的过程

面试遇到一个问题:hashmap将值映射到hash数组上的具体过程,答得不好,所以在此重新梳理一遍。

第一个过程是通过键计算出hash值的过程。即下面hash(key)的过程。

HashMap源码:

public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

  由此可见:hashmap通过:(h = key.hashCode()) ^ (h >>> 16)计算出hash值。

hashCode()是Object的一个Java内部封装的方法,它会根据特定规则产生一个32位的hashcode。

为什么这样计算呢?   因为哈希数组的长度远远达不到2^16.后续通过hash计算在hash数组的位置时用不到高16位。通过这种无符号右移+异或方式,HashMap 的哈希函数将原始哈希码的高位信息与低位信息结合在一起,产生了更加均匀分布的新哈希值。这有助于在 HashMap 的内部数组中更均匀地分布数据,从而减少了哈希冲突,提高了数据结构的整体性能。

Object的hashcode方法:

第二个过程是通过hash值计算出hash数组索引的过程:

计算过程:

p = tab[i = (n - 1) & hash}]

p即为所要插入到的hash数组的位置的索引,通过(n-1)& hash计算得出。n为数组的长度。

hashmap规定数组的长度必须为2的倍数,当长度为2的倍数时,hash % n = hash & (n – 1),

与数组长度进行取余计算就是非常经典的一个计算索引位置的方法。

为什么要采用2进制的方法计算呢?

位运算的计算效率更高。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值