沙盒粉碎模拟器
106.24 MB · 2025-12-20
原文来自于:zha-ge.cn/java/35
在 JDK 1.8 之前,HashMap 采用"数组 + 链表"的数据结构。当发生哈希冲突时,新元素会被添加到链表的头部或尾部。这种设计在正常情况下工作良好,但存在一个致命缺陷:当大量元素映射到同一个桶时,链表会变得很长,导致查询性能急剧下降。
想象一下,如果一个桶中的链表有 1000 个元素,那么在最坏情况下,查找一个元素需要遍历整个链表,时间复杂度退化为 O(n),完全失去了哈希表应有的 O(1) 查询优势。
更严重的是,这个特性可能被恶意利用。攻击者可以精心构造大量具有相同哈希值的字符串,强制它们映射到 HashMap 的同一个桶中,形成极长的链表。这种哈希碰撞攻击可以让服务器的 CPU 使用率飙升,造成拒绝服务攻击(DoS)。
JDK 1.8 引入红黑树正是为了解决这个问题。新的设计规则如下:
这样的设计兼顾了两种数据结构的优势:
你可能会问,为什么不选择 AVL 树或其他平衡二叉树?答案在于权衡:
HashMap 引入红黑树是一个典型的工程优化案例。它不仅解决了链表在极端情况下的性能问题,还有效防范了哈希碰撞攻击。这个改进体现了 Java 团队对性能和安全性的持续关注,也展现了在数据结构设计中"没有银弹,只有权衡"的工程哲学。
通过这个优化,HashMap 在保持原有简单易用特性的同时,获得了更加稳定和可靠的性能表现,这正是一个成熟框架应有的品质。