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

java中SLinkedList中removeFirst()方法的实现,java,garbage-collection,adt,Java,Garbage Collection,Adt,我从一本书中获得了以下代码,用于实现单链接列表。我不理解removeFirst()方法中的一些代码行,该方法从LinkedList中删除第一个节点 class ListNode{ private String element; private ListNode next; public ListNode(){ element = null; next = null; } public ListNode(String s,

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

这取决于链表的整个实现,您的问题中没有包括链表。但是,如果对象即使在从列表中删除了if之后也可以保留对节点的引用,则需要该行

假设我们有一长串节点
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

让我们假设,节点的单链链表是:
A-->B-->C-->D
,头部节点是A。现在,让我们看看removeFirst()方法。当它被调用时,
if(head==null)
条件不满足,因为我们的head节点“A”不是null。然后执行else语句,
temp=head
//将head引用带入临时变量
head=head.getNext()//由于我们要删除第一个节点,即head,因此我们将head设置为下一个节点(即head-->next),即节点“B”
现在,要删除A(第一个节点),我们需要断开A(前一个头部)->B(当前头部)之间的连接,这将由
temp.setNext(空)//所以输出链表变成了B-->C-->D
然后,由于一个节点被删除,所以在下一个语句中,它将链接的大小减少
大小--


我认为我们还将temp引用设置为NULL,作为
temp=NULL
,以使删除的节点符合垃圾收集的条件。

请参阅,因为该列表是双链接列表。我猜删除第一个元素后head.previous应该为null。该列表是一个单链接列表。正如@Thinkingcaps comment中的答案所示:迭代器保留对ListNodes的引用。为了响应@keuleJ的注释,我编辑了我的答案。这一行是必需的。假设我们有一个单链表a->B->C->D。现在我们在removeFirst()方法引用a中定义了一个局部变量,而a仍然保留对B的引用,而没有设置为null。我们将head作为一个实例变量设置为B。那么在调用removeFirst()方法之后,GC会收集A吗?这是如何工作的?问问你自己,“我可以写代码访问一个数据库吗?”如果答案是否定的,它将被收集。在这里的示例中,一旦退出
removeFirst()
方法,将无法访问并收集。因此答案是
No
如果您只是提取已删除节点的值,则不需要将next设置为null!即使您不这样做:temp.setNext(null)---[temp]很快将由GC收集
for (Iterator<String> i = list.iterator();;i.hasNext())