HashMap对hashcode进行扰动计算后为何在计算indexFor时,不直接return h

菠萝印象威 2020-09-30 11:07:12
HashMap中有两段源码hash 和 indexFor 1.hash的源码是对key的hashcode进行扰动计算,主要是防止不同的hashcode的高位不同,但低位相同,导致hash冲突,做法是将key的hashcode与自身的高16位进行异或操作 2. indexFor计算可了key在数组中的位置h&(length) 问题一:为何只与它的高16位异或,我知道HashMap的容量为2的幂次方,但上限为2的16次方是为何 问题二:既然扰动函数已经很大程度解决了hash冲突,为何在计算key在tab数组中的位置时不直接用扰动后的hash值,还要再让h和length-1与操作 主要问题是既然已经对key的hashcode进行扰动操作,使得其更加散列,为何在插入数组时不直接用这个hash值,是因为还不够散列吗。
...全文
661 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
超人小冰 2020-09-30
  • 打赏
  • 举报
回复
h&(length) 是对 除法取余的优化。你的map长度为N,你存储的位置肯定也只能为1-N之间
大隐藏于寺 2020-09-30
  • 打赏
  • 举报
回复
你可以去随便试一下三五个字母的字符串使用HashMap的hash()方法计算扰动后的hash值,不会很小,如果直接使用扰动后的hash值作为数组下标,那就需要数组长度足够大.比如下面的demo.

    public static void main(String[] args) throws InterruptedException {
        String a = "a";
        String d = "demo";
        String e = "abc";
        int aHashcode = a.hashCode();
        int dHashcode = d.hashCode();
        int eHashcode = e.hashCode();
        System.out.println(aHashcode ^ (aHashcode >>> 16)); //输出97
        System.out.println(dHashcode ^ (dHashcode >>> 16));//输出3079629
        System.out.println(eHashcode ^ (eHashcode >>> 16));//输出96355

    }

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧