我们正在尝试编写一种方法,用于从LUT的链表实现中删除具有特定键的节点。
我写的代码摘要:
public void delete (String k) {
Node currNode = listHead;
Node prevNode = listHead;
Key key = new Key (k);
while (!currNode.key.equals(k) && currNode != null){
prevNode = currNode;
currNode = currNode.next;
}
if (currNode == listHead) {
listHead = listHead.next;
} else {
prevNode.next = currNode.next;
}
}
我的朋友基本上写了相同的东西,但没有使用前一个节点指针,而是写作他的最后一行:
currNode = currNode.next //detach point, override
这些都是等价的吗?我认为我对它的Java内存管理感到困惑
如果您已经在其他地方创建了listHead
节点,那么就写下:
Node currNode = listHead;
currNode
仅存储对存储listHead
的内存位置的引用,对吧?所以在你执行currNode = currNode.next
的while循环中,你正在做的是进入currNode
中引用的内存位置,然后查看下一个变量并将引用存储在{{1}中。 1}?所以基本上更新currNode
所指向的位置。这意味着我朋友的代码错了,对吧?由于他的代码同样意味着:“使用currNode
”的内存位置更新currNode
中当前的引用。
有人会介意帮我除雾吗?
答案 0 :(得分:3)
您的朋友不可能是正确的,因为必须更改.next
的{{1}}字段才能从列表中删除Node
。
我想你知道,要从列表中删除节点Node
,您需要设置节点N
的{{1}}字段以引用节点.next
。你朋友的方法不可能这样做,因为它没有改变任何节点的N-1
字段。
至于内存,一旦N+1
的{{1}}字段引用.next
,则列表不再保留N-1
。它是否有资格进行垃圾收集取决于程序中是否有其他内容引用它。但是这份清单现在已经洗掉了。
答案 1 :(得分:2)
您的查询已经得到了正确的答案,但您的代码中有一些错误不适合评论。
<强> NullPointerException
强>
您的while
循环条件是向后的。它应该是
while (currNode != null && !currNode.key.equals(k)) { ... }
当您到达列表末尾或列表中没有要开始的节点时,请避免使用NullPointerException
。
未找到值
该方法不处理列表中不包含k
的情况。您需要在while循环后检查currNode
null
。
if (currNode != null) {
if (currNode == listHead)
listHead = listHead.next;
else
prevNode.next = currNode.next;
}
答案 2 :(得分:1)
您的分析是正确的 - 您朋友的代码实际上不会从列表中删除该节点。
我认为使用调试器逐步执行代码可能有助于消除迷雾。如果您还没有使用集成开发环境(IDE),我建议使用IntelliJ IDEA,Eclipse或Netbeans - 所有这些都包含调试器。