HashMap 的 remove 方法是如何实现的?
·
💡 核心结论:一句话先记住
HashMap 的 remove(key) 就像去寄物柜拿走你的行李:先通过密码(Hash)定位到是哪个柜子,打开柜子看一眼,如果是链表就解开前后指针,如果是红黑树就把树砍掉一个树枝并重新调整平衡。拿完如果发现树上的果子太少了,它还会把树重新退化成普通链表。
🔍 remove 执行的 4 大核心步骤
1. 定位柜子(算 Hash)
你给它一个 Key,它先噼里啪啦一顿计算,算出这个 Key 该存放在数组的哪个格子里(桶位)。如果这个格子本来就是空的,说明根本没这个人,直接返回 null。
2. 区分看门的是谁(链表 or 红黑树)
找到格子后,根据里面装的数据结构不同,采取不同的拆解办法:
- 如果是普通链表: 挨个对比 Key,找到了就执行“过河拆桥”。比如要删 B(A -> B -> C),直接让 A 的小手指向 C(A -> C),B 就被孤立踢出局了。
- 如果是红黑树: 树结构删除可就复杂了,不仅要把节点摘掉,还要进行左旋、右旋、重新变色,确保整棵树依然是平衡的(不然树歪了查询就慢了)。
3. 触发“退树化”(缓冲机制)
如果刚才删的是红黑树里的节点,删完之后 HashMap 会数一数这棵树上还剩几个节点。如果节点数减少到 6 个或更少,它就会觉得“杀鸡焉用牛刀,树太小了维护起来太累”,就会调用底层方法把这棵树重新变回普通的拉链单链表。
4. 吐出老数据(返回 Value)
成功删除后,它会把刚才删掉的那个数据的值(Value)返回给你,让你知道你到底删了个啥。
⚠️ 工作和面试中的两大“隐藏大坑”
坑一:删除了元素,HashMap 占用的内存空间会变小吗?
- 答案是:绝对不会!
remove()方法只删数据,不缩容。这就好比你把寄物柜里的东西拿空了,但那排大柜子依然放在商场里占地方。如果你的 Map 曾经塞过几百万条数据,哪怕你全部remove掉,底层巨大的数组依然躺在内存里。想要彻底释放内存,必须调用clear()方法(把每个格子彻底置为null让 GC 回收),或者直接把整个 Map 置为null。
坑二:remove() 和 clear() 有啥区别?
remove(key)是精确定位,只切掉某一个瘤(时间复杂度在 O(1)O(1)O(1) 到 O(logn)O(\log n)O(logn) 之间)。clear()是全面扫除,把所有格子的指针全部切断,不管里面有多少东西通通变空(时间复杂度是 O(n)O(n)O(n),需要遍历整个大数组)。
🎯 秒记口诀
定位桶位看类型,链表直接改指针。
红黑树删复杂看,旋转变色保平衡。
节点少于 6 退树,只删数据不缩容!
更多推荐



所有评论(0)