前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Java面试小短文】HashMap中的hash方法为什么要右移16位并异或?

【Java面试小短文】HashMap中的hash方法为什么要右移16位并异或?

作者头像
砖业洋__
发布2023-05-06 20:42:21
2390
发布2023-05-06 20:42:21
举报
文章被收录于专栏:博客迁移同步博客迁移同步

HashMap中的hash方法为什么要右移16位并异或?

代码语言:javascript
复制
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

  原因是为了让hash值的散列度更高,尽可能的去减少hash表的hash冲突,从而去提升数据的查找性能。

代码语言:javascript
复制
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;          
        // .......源码自行查看,只展示关键部分
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        // .......源码自行查看,只展示关键部分
    }

  在HashMapput方法里面,是通过keyhash值与数组的长度取模计算得到的一个数组位置。而在绝大部分情况下,n的值一般是小于2^16(就是65536),这就意味着 i 的值始终是使用hash值的低16位与(n - 1)进行取模计算,这是由 & 运算符的特点决定的,这样就会造成key的散列度不是很高,导致大量的key集中存储在一个固定的几个数组位置上,很显然这会影响到数据的查找性能。因此为了提升keyhash值的一个散列度,在hash方法里面做了一个位移运算。

  所以在hash方法里面,首先使用keyhashCode无符号右移16位,意味着把hashCode的高位移动到了低位,然后再用hashCode与右移之后的值进行异或运算。就相当于把高位和低位的特征进行了组合,这样通过高位和低位组合后的hashCode通过 & 运算符进行运算后,它得到的一个数组的位置的散列度一定会更高,通过这种方式,可以去降低hash冲突的概率。

上面说是通过keyhash值与数组的长度取模计算得到的一个数组位置。取模计算?哪里取模了?(n - 1) & hash是取模吗? 真的是取模,只要n是2的指数幂,就可以将取模运算改成位运算 比如:13 % 4 = 1 —> 13 & (4 - 1) = 1  00001101 (13) & 00000011  (4 - 1) = 00000001  (1) 比如 14 % 8 = 6 —> 14 & (8 - 1) = 6  00001110 (14) & 00000111  (8 - 1) = 00000110  (6) 你学到了吗

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • HashMap中的hash方法为什么要右移16位并异或?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档