繁体   English   中英

简单的 HashMap 删除函数不会更新地图条目

[英]Simple HashMap remove function doesn't update the map entries

我正在尝试实现一个简单的哈希映射,其中映射的每个条目都表示为一个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中定位key的索引位置,然后线性扫描这个entry中的每个节点,并移除map中匹配的key:

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--;
        }
}

它不会使匹配的nodes从外部节点中删除,只有引用的局部变量受到影响。 由于我有对节点的引用,我想从nodes中删除它(如果有匹配的键),拥有它的地址并尝试将其尊重为null ,但它是无效的。 我很高兴听到一些解释为什么这段代码不起作用。

我有一个像这样的简单测试:

MyHashMap map = new MyHashMap();
map.put(1, 1);
map.put(2, 1);
map.remove(1);
System.out.println(map.get(1)); // still returns 1

您的局部变量nodenodes[hash]副本 分配给副本不会更改原件。 您需要更改代码以更新原始代码。 而且您不需要检查node.next是否等于null :没关系,如果它是null您将分配null ,这正是您想要的。

if (node.key == key) {
    if (prev != null) {
        prev.next = node.next;
    } else {
        nodes[hash] = node.next;
    }
    size--;
}

检查 node.next 不等于 null 是错误的。 您不应该关心下一个元素,永远不会引用已删除元素中的下一个元素。 HashMap 的源代码是:

if (node == p)
   tab[index] = node.next;
else
   p.next = node.next;
++modCount;
--size;

'p' 是你的 'prev' 的方法。HashMap 将值分配给这个散列中的第一个元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM