简体   繁体   English

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

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

I'm trying to implement a simple hash map in which each entry of the map is represented as a Node single linked list, and I have an array of entries such as Node[] nodes :我正在尝试实现一个简单的哈希映射,其中映射的每个条目都表示为一个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;
        }
}

Here is the remove method, which first tries to locate the index position of the key in the HashMap, and then scans linearly each node in this entry and removes the matched key in the map:这里是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--;
        }
}

It doesn't make the matched node removed from the nodes outside and only the local variable referenced is affected.它不会使匹配的nodes从外部节点中删除,只有引用的局部变量受到影响。 Since I have a reference to the node I want to remove it from the nodes (in case there is a matched key), having its address and trying to deference it to null , but it's invalid.由于我有对节点的引用,我想从nodes中删除它(如果有匹配的键),拥有它的地址并尝试将其尊重为null ,但它是无效的。 I'm glad to hear some explanation why this code doesn't work.我很高兴听到一些解释为什么这段代码不起作用。

I have a simple test like this:我有一个像这样的简单测试:

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

You local variable node is a copy of nodes[hash] .您的局部变量nodenodes[hash]副本 Assigning to a copy doesn't change the original.分配给副本不会更改原件。 You need to change your code so that it updates the original.您需要更改代码以更新原始代码。 And you don't need to check whether node.next equals null : it doesn't matter, if it's null you will assign null and that's precisely what you want.而且您不需要检查node.next是否等于null :没关系,如果它是null您将分配null ,这正是您想要的。

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

It's wrong to check node.next not equals null.检查 node.next 不等于 null 是错误的。 You shouldn't care the next element, The next element from the removed one will never be referred.您不应该关心下一个元素,永远不会引用已删除元素中的下一个元素。 The source code from HashMap is: HashMap 的源代码是:

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

The 'p' is approach to your 'prev'.The HashMap assign the value to the first element in this hash earlier. 'p' 是你的 'prev' 的方法。HashMap 将值分配给这个散列中的第一个元素。

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

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