在Java中HashMap如何工作_Java哈希表原理解析-java教程

hashmap用(table.length – 1) & hash计算数组下标,要求容量为2的幂以保证位运算等效取模;hash值经扰动处理,链表长度≥8且数组长度≥64才树化;key必须正确实现hashcode和equals。

HashMap怎么算出数组下标?不是用 % 取模

很多人以为 index = hashCode % table.length 是 HashMap 定位桶的逻辑,其实不是。JDK 8+ 实际用的是位运算:(table.length - 1) & hash。前提是数组长度必须是 2 的幂(如默认 16、32、64…),这样 length - 1 就是形如 0b1111 的掩码,位与操作比取模快得多,也避免负哈希值导致的索引越界问题。

但这也意味着:如果你传入非 2 的幂的初始容量(比如 new HashMap(17)),HashMap 会自动向上找最近的 2 的幂(这里是 32)——所以别硬凑奇数容量,白费力气。

  • 自定义 key 类时,hashCode() 要尽量分散,否则高位信息丢失严重,加剧碰撞
  • 如果 key 是字符串,Java 已优化过其 hashCode(),一般不用重写;但若 key 是自定义对象,且参与 equals 比较的字段没全用于计算 hashCode,就会出 bug
  • 注意:hash() 方法在 JDK 中还会对原始 hashCode 做一次扰动(高 16 位异或低 16 位),进一步降低低位冲突概率

为什么链表长到 8 就转红黑树?不是 7 也不是 9

这个阈值 TREEIFY_THRESHOLD = 8 是经过数学推导和大量压测平衡出来的:泊松分布下,当负载因子为 0.75 时,链表长度达到 8 的概率已低于百万分之一。换句话说,正常均匀哈希下,几乎不会触发树化——它防的是极端碰撞场景,不是日常使用。

但光长度够还不行,还得满足另一个条件:table.length >= MIN_TREEIFY_CAPACITY(即 ≥ 64)。否则即使链表超长,也只扩容,不树化。这是为了防止小数组+短链表就强行树化,反而增加内存和维护开销。

立即学习“Java免费学习笔记(深入)”;

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » 在Java中HashMap如何工作_Java哈希表原理解析-java教程
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3999007+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3999007+
  • 本周更新: 0+
  • 最后更新: 2026-03-16