簡體   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