码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • HashMap中的hash 方法


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

    之所以要对 hashCode 无符号右移 16 位并且异或,核心目的是为了让 hash 值的散列度更高,尽可能减少 hash 表的 hash 冲突,从而提升数据查找的性能。

    HashMap 的 put 方法

    在 HashMap 的 put 方法里面,是通过 Key 的 hash 值与数组的长度取模计算 得到数组的位置。
    而在绝大部分的情况下,n 的值一般都会小于 2^16 次方,也就是 65536。所以也就意味着 i 的值 , 始终是使用 hash 值的低 16 位与(n-1)进行取模运算,这个是由与运算符&的特性决定的。
    这样就会造成 key 的散列度不高,导致大量的 key 集中存储在固定的几个数组位置,很显然会影响到数据查找性能。
    1. final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
    2. boolean evict) {
    3. Node[] tab; Node p; int n, i;
    4. if ((tab = table) == null || (n = tab.length) == 0)
    5. n = (tab = resize()).length;
    6. if ((p = tab[i = (n - 1) & hash]) == null)
    7. tab[i] = newNode(hash, key, value, null);
    8. else {
    9. Node e; K k;
    10. if (p.hash == hash &&
    11. ((k = p.key) == key || (key != null && key.equals(k))))
    12. e = p;
    13. else if (p instanceof TreeNode)
    14. e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);
    15. else {
    16. for (int binCount = 0; ; ++binCount) {
    17. if ((e = p.next) == null) {
    18. p.next = newNode(hash, key, value, null);
    19. if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
    20. treeifyBin(tab, hash);
    21. break;
    22. }
    23. if (e.hash == hash &&
    24. ((k = e.key) == key || (key != null && key.equals(k))))
    25. break;
    26. p = e;
    27. }
    28. }
    29. if (e != null) { // existing mapping for key
    30. V oldValue = e.value;
    31. if (!onlyIfAbsent || oldValue == null)
    32. e.value = value;
    33. afterNodeAccess(e);
    34. return oldValue;
    35. }
    36. }
    37. ++modCount;
    38. if (++size > threshold)
    39. resize();
    40. afterNodeInsertion(evict);
    41. return null;
    42. }

    HashMap 的 hash 方法

    为了提升 key 的 hash 值的散列度,在 hash 方法里面,做了位移运算。首先使用 key 的 hashCode 无符号右移 16 位,意味着把 hashCode 的高位移动到了低位。然后再用 hashCode 与右移之后的值进行异或运算,就相当于把高位和低位的特征进行和组合。从而降低了 hash 冲突的概率。如下图:
    1. static final int hash(Object key) {
    2. int h;
    3. return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    4. }

  • 相关阅读:
    Android7.1 ROOT权限的获取
    GIC/ITS代码分析(12)LPI中断虚拟化之QEMU中ITS设备的模拟
    学习C++第二十四课--成员函数模板,模板显示实例化与声明笔记
    快速上手Django(七) -Django之登录cookie和session
    SpringBoot+Vue开发记录(四)
    电脑怎么设置开机密码?简单几步给你的电脑“上锁”
    【Flutter】Flutter 包管理(13)国际化 使用 intl 包处理 负数 性别 双向文本 复杂的日期和数字格式化
    LVS+DR部署
    TechEmpower 21轮Web框架 性能评测 -- C# 的性能 和 Rust、C++并驾齐驱
    如何建立用户关注与青睐的产品设计?
  • 原文地址:https://blog.csdn.net/qq_63431773/article/details/133188287
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号