在java中的SLinkedList中实现removeFirst()方法

时间:2015-03-30 15:16:42

标签: java garbage-collection adt

我从一本书中获得了以下代码,用于实现单链表。我不理解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新手,有什么建议或想法吗?

2 个答案:

答案 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,以使已删除的节点符合垃圾回收的条件。