You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义简易HashMap的remove方法无法更新映射条目问题求助

简易HashMap的remove方法失效原因分析

我尝试实现一个简易HashMap,用Node单向链表表示映射条目,通过Node[] nodes数组存储这些条目:

static final class Node {
        int key;
        int value;
        Node next;
        int hash;

        Node(int key, int value, Node next, int hash) {
            this.key = key;
            this.value = value;
            this.next = next;
            this.hash = hash;
        }
}

下面是我写的remove方法,逻辑是先定位键在HashMap中的索引,再线性扫描对应链表节点并移除匹配的键:

public void remove(int key) {
        int hash = computeHash(key);
        Node node = nodes[hash];
        if (node == null) {
            return;
        }

        Node prev = null;
        while (node.key != key && node.next != null) {
            prev = node;
            node = node.next;
        }
        if (node.key == key) {
            if (prev != null) {
                prev.next = node.next;
            } else if (prev == null) {
                node = node.next;
            } else {
                node = null;
            }
            size--;
        }
}

调用这个方法后,即使执行了remove操作,调用get仍能获取对应值,比如测试代码:

MyHashMap map = new MyHashMap();
map.put(1, 1);
map.put(2, 1);
map.remove(1);
System.out.println(map.get(1)); // 仍然返回1

失效原因拆解

  1. 局部变量引用修改不影响原数组
    当要删除的是链表的头节点(也就是prev == null的情况),代码里的node = node.next;只是修改了局部变量node的指向,完全没有改动nodes[hash]这个数组元素的引用。原数组里的这个位置依然指向原来的头节点,所以get方法依然能找到它。

  2. 冗余的else分支
    代码里的else { node = null; }永远不会被执行,因为前面已经用if (prev != null)和else if (prev == null)覆盖了所有情况,这个分支完全多余。

修复方案

当prev == null时,需要直接修改数组的对应位置,把它指向头节点的下一个节点:

if (prev != null) {
    prev.next = node.next;
} else {
    // 直接修改数组中的引用,替换头节点
    nodes[hash] = node.next;
}

这样就能真正把原数组里的头节点引用替换掉,删除操作才会生效。

内容的提问来源于stack exchange,提问作者Nam V. Do

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:54:48