欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > HashMap的奇幻漂流:当一个数组决定去整容

HashMap的奇幻漂流:当一个数组决定去整容

2025/5/3 3:47:03 来源:https://blog.csdn.net/CSDN_WHO/article/details/146267489  浏览:    关键词:HashMap的奇幻漂流:当一个数组决定去整容

标准答案(面试官最爱版)

HashMap实现原理

  1. 数据结构:数组+链表/红黑树(Java 8+)
  2. 哈希算法(h = key.hashCode()) ^ (h >>> 16)
  3. 索引计算(n-1) & hash(n为数组长度)
  4. 冲突解决:链表→红黑树(阈值=8),树→链表(阈值=6)
  5. 扩容机制:2倍扩容,负载因子默认0.75

用程序员黑话:

“它就是个会变形的瑞士卷——平时是夹心饼干(数组+链表),吃撑了变千层蛋糕(红黑树)”


一、初入江湖:数组的容貌焦虑

1.1 基础人设:图书馆管理员

假设你有个16层的书架(数组),每层放着:

  • 空书架:等待书籍(Entry)入驻
  • 单本书:直接上架(没有哈希冲突)
  • 一摞书:链表结构(哈希碰撞时叠罗汉)
  • 精装书柜:红黑树形态(当书堆超过8本)
// 典型书架结构
[null,Node<K,V>,        // 单本书TreeNode<K,V>,    // 精装书柜LinkedList<Node> // 书堆
]

1.2 哈希函数:图书编号玄学

图书上架流程:

public int hashCode() {return 作者姓氏首字母.charCodeAt(0) * 31+ 书名首字母.charCodeAt(0); // 31是玄学质数
}

现实往往是:

  • 《百年孤独》和《白夜行》可能挤在同一层(哈希碰撞)
  • 管理员(HashMap)碎碎念:“都怪马尔克斯和东野圭吾姓氏首字母都是B!”

二、冲突解决:书架的生存战争

2.1 链表模式:叠罗汉的艺术

当新书到来时:

  1. 先按哈希值找楼层
  2. 如果该层已有书:
    • Java 7:新书放最上面(头插法)
    • Java 8:新书放最下面(尾插法)

为什么改尾插法?

答:为了防止多线程扩容时形成环形链表(曾经导致CPU 100%的惨案)

2.2 红黑树模式:卷王诞生

当某层书堆超过8本:

if (binCount >= TREEIFY_THRESHOLD - 1) {treeifyBin(tab, hash); // 呼叫变形金刚!
}

变形代价:

  1. 需要书架总层数≥64(MIN_TREEIFY_CAPACITY)
  2. 消耗CPU给书堆做美甲(树化操作)

降级机制:当书减少到6本时,变回普通书堆(防止频繁转换)


三、扩容风暴:图书馆扩建计划

3.1 触发条件:书架负载率超75%

if (size > threshold) {resize(); // 警报!需要扩建!
}

扩建流程:

  1. 新书架扩容2倍(16→32层)
  2. 旧书籍重新计算楼层:
    • 原楼层 或 原楼层+旧容量(二进制魔术)
    • 例如旧楼层=5(0101),新楼层=5或5+16=21

3.2 死亡遍历:多线程的噩梦

未同步的HashMap在扩容时:

  • 线程A正在搬书到新书架
  • 线程B突然来借书
  • 结果可能:拿到null、死循环、数据丢失

解决方案

用ConcurrentHashMap——给每个书架配保安(分段锁)


四、使用禁忌:程序员的防秃指南

4.1 自定义对象的坑

class Student {String name;// 忘记重写hashCode和equals...
}// 使用后果:
map.put(new Student("张三"), 90);
map.get(new Student("张三")); // 返回null(当场秃头)

4.2 负载因子调参玄学

  • 设0.9:节省内存但容易碰撞(书架挤成沙丁鱼罐头)
  • 设0.5:查询快但内存翻倍(每个书架只放半本书)

黄金建议:非必要别动默认0.75,这是数学家算出来的魔法数字


五、灵魂拷问:为什么不用二叉搜索树?

  1. 树化成本高:链表变树要旋转染色(美甲时间)
  2. 退化合订本:树节点占用内存是链表的2倍
  3. 小数据优势:链表在少量数据时遍历更快

用生活比喻:

整理5本书用书堆(链表)更快,整理50本书才需要书柜(红黑树)

请添加图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词