我从一本书中获得了以下代码,用于实现单链表。我不理解removeFirst()
方法中的一些代码行,它会从LinkedList中删除第一个节点。
class ListNode{
private String element;
private ListNode next;
public ListNode(){
element = null;
next = null;
}
public ListNode(String s, ListNode n){
element = s;
next = n;
}
//Access method
public String getElement(){
return element;
}
public ListNode getNext(){
return next;
}
//Modify method
public void setNext(ListNode n){
next = n;
}
}
public String removeFirst(){
if(head == null)
return null;
else{
ListNode temp = head;
head = head.getNext();
temp.setNext(null); //Which I don't understand, is it necessary?
size --;
return temp.getElement();
}
}
似乎可以省略语句temp.setNext(null);
。那么为什么它在这里,它与java中的垃圾收集有什么关系。既然我是Java新手,有什么建议或想法吗?
答案 0 :(得分:1)
这取决于链接列表的整个实现,您没有将其包含在您的问题中。但是,如果对象可以保留对节点的引用,即使已从列表中删除,则该行也是必需的。
假设我们有一长串节点A -> B -> C -> ...
。假设所有这些节点都已从列表中删除,但我们仍保留对A
的引用。如果所有节点仍然保持对下一个节点的引用,则这将阻止所有节点被垃圾收集。只需将下一个节点设置为null
,即可确保只能对A
进行垃圾回收。
链接列表的实现可能意味着可以保留对节点的引用。例如,Iterator
的许多实现都包含对当前节点的引用。
考虑以下代码:
Iterator<String> iterator = list.iterator();
while (i.hasNext()) {
if ("foo".equals(i.next())) {
i.remove();
break;
}
}
// lots more code
此代码在列表中搜索String
"foo"
的第一个匹配项。如果找到,它将从列表中删除"foo"
并从循环中断开。这样做的问题在于Iterator
i
仍然在剩余代码的范围内,并且仍然保留对节点的引用。如果发生break
,则此节点可能位于列表的中间。如果不将next
设置为null
,这将阻止所有后续节点在i
仍在范围内时进行垃圾回收,即使列表已清除。
请注意,您通常应该在循环中创建一个迭代器,例如
for (Iterator<String> i = list.iterator();;i.hasNext())
答案 1 :(得分:0)
让我们假设,单个链接的节点列表是:A --> B --> C --> D
,头节点为A.现在,让我们通过你的 removeFirst()方法。当它被调用时,if(head == null)
条件不满足,因为我们的头节点“A”不是NULL。然后它执行else语句,
temp = head
//将头部引用转换为临时变量
head = head.getNext();
//因为我们要删除第一个头部的节点,所以我们设置头到下一个节点(即头部 - >接下来),即节点“B”
现在,要删除A(第一个节点),我们需要断开A(前一个头)之间的连接 - &gt; B(当前负责人)将由中国人完成
temp.setNext(null);
//所以链接列表变为A B - &gt; C - &gt; D
然后当一个节点被删除时,所以在下一个语句中,它会减少size--
的链接大小。
我认为我们还将临时引用设置为NULL temp=NULL
,以使已删除的节点符合垃圾回收的条件。