当前位置: 首页 > news >正文

问HashMap底层原理?

HashMap是基于数组+链表+红黑树的哈希表。用于存储键值对。

1.哈希计算和扰动处理,也就是Hash方法

每一个Object都有一个 .hashCode 方法。

  1. (哈希计算)在对hashmap进行插入和查询时,先调用key键的key.hashCode()方法获取一个未处理的int哈希值,在底层代码中该值被复制给变量h
  2. (扰动处理)通过异或运算,也就是一位一位比较,如果不同就是1,如果相同就是0。h^(h>>>16)>>>无符号右移操作符,它会将 h 的二进制表示向右移动 16 位,高位用 0 填充,这样就可以将高位的信息混入低位,让哈希值在低位也均匀分布,减少碰撞。

2.索引定位

在原来手动计算的时候,我们是通过取模运算来确定的。在底层是通过(n-1)&hash计算哈希桶bucket下标,效率比取模更高。(原理)

为什么用这个公式?

  1. n-1,在进行了2^n-1后,低位全是1,高位全是0。变成了低位全1的掩码。
  2. 取模运算是算数运算,位运算是底层硬件级操作。且hash&(n-1)hash%n结果完全一样
  3. 20%16=4,20=00010100,20&15=00000100=4

​ 00001111

3.冲突处理

  1. 如果桶的位置为空直接放入新大街店
  2. 如果存在节点,就逐个比较,如果equals()相等就覆盖value,否则追加到链表尾部
  3. 当单个桶中的节点数查过8且数组容量>=64,链表会转换成红黑树来降低最坏复杂度O(log n)

4.扩容机制

  • 默认初始数组长度是16,负载因子是0.75
  • 当元素超过阈值,数组扩容两倍,并重新分配节点位置
  • 扩容后的新下标计算不是不是重新算hashCode,而是用(node.hash&oldCap)判断要留在原位置还是移动到原位置+oldCap。如果端出来的数值是0就放到相应原位置,否则放到原数组长度+目前索引的位置。(原理)
  • )HashMap扩容时,node.hash & oldCap的作用是快速确定节点在新数组中的位置。由于oldCap是2的幂次方,其二进制只有一位为1,其余全为0,因此按位与运算的结果仅由节点哈希值中与该位对应的那一位决定——若该位为0,结果为0,节点在新数组中的位置与原位置相同;若该位为1,结果等于oldCap,节点新位置则为原位置加上oldCap。这种设计的巧妙之处在于,每次扩容都以2倍增长(保持2的幂次方),使得oldCap的二进制独有的1位会左移一位,刚好对应新容量比旧容量多出的判断位,通过一次简单的位运算就能完成节点分流,大幅提升扩容效率。
if((node.hash&oldCap)==0)-->放到newTable[i]
else 						放到newTable[i+oldCap]
http://www.hskmm.com/?act=detail&tid=7316

相关文章:

  • 用 Go 重写 adbkit:原理、架构与搭建实践
  • C语言环境搭建之Linux子系统使用vscode连接子系统
  • 移远AT指令笔记
  • C++ 智能指针
  • 数据类型
  • iphone运行windows系统
  • NVR接入录像回放平台EasyCVR视频融合平台语音对讲配置指南
  • Ubuntu filebrowser网盘工具安装
  • 图片结构 - voasem
  • ESP32做AP,ESP8266做station,遥控
  • 实用指南:25年高联:一试填空题解析(下篇)
  • Spring AOP 面向切面编程 - 浪矢
  • jvm内存泄漏的排查tips总结
  • IPA
  • Chromium历史版本下载方式
  • 【ACM出版】第三届物联网与云计算技术国际学术会议 (IoTCCT 2025)
  • 2025年最全 Wiki 管理工具测评:ONES、Confluence、Notion......哪个更适合你?
  • 详细介绍:用户争夺与智能管理:定制开发开源AI智能名片S2B2C商城小程序的战略价值与实践路径
  • PlorarD(WEB中等)
  • 神经网络稀疏化设计构架方式和原理深度解析
  • 天下拍拍卖系统:二方系统也能扩展三方平台功能
  • express使用redis
  • day07 课程
  • 111
  • 排序实现java - 教程
  • .net core 发布到 iis 步骤
  • kylin SP2安装mysql8.4.5
  • 微信社群机器人接口
  • C++的枚举类
  • Revit二次开发 钢筋生成API(一)