3

我有一个单链表

a->b->c->d->e

a,b,c,d 和 e 是节点类型的对象。我想在遍历列表时删除一个节点,然后将删除的节点作为列表的头部,如下面的代码所示

list.delete(iterator, current);
list.addObjectAtFront(current);


public void delete(ListIterator li, Node node) {
    if (li == null) {
        throw new NullPointerException();
    }

    li.next();
    if (li.previous() != null) {
        li.previous().setNext(node.getNext());
    }

}

public void addObjectAtFront(Object o) {
    Node newNode = new Node(null, o);
    if (this.head != null) {
        newNode.setNext(this.head);
        this.head = newNode;
    } else {
        this.head = this.tail = newNode;
    }
}

调用上述方法时,假设当前项目为 c。我期待以下

list.delete(iterator, current);
Output: a->b->d->e
list.addObjectAtFront(current);
Output: c->a->b->d->e

我有两个相互矛盾的想法

  1. 删除后,c 不再指向任何其他节点,可以在调用第二种方法之前进行垃圾收集。

  2. c 不能被垃圾收集,因为它本身不是 null 并且里面有一些数据。这意味着如果我不需要使用 c; 它只会在记忆中徘徊。

哪一个是正确的,还是我完全弄错了,需要对对象引用有新的理解?

4

3 回答 3

3

垃圾收集永远不会删除您有任何引用方式的内存(除非您使用Wea​​kReference

也就是说,如果您仍然可以使用该节点,请确保 java 不会将它从您身上垃圾收集起来。作为程序员,您不需要考虑垃圾收集器的行为方式,除非它是为了提高性能。GC 不应该影响代码的正确性。

哪一个是正确的,还是我完全弄错了,需要对对象引用有新的理解?

直接回答,也不是。当您删除时,您使用对名为 的节点的引用current。此参考与 c 的参考相同。当 c 被删除时,您仍然有 current 正在引用它。然后将 current 添加到列表的前面。现在您再次有 2 个引用,然后当它从范围下降时您会丢失当前引用,从而使您回到 1 个引用。

c 永远不会收集垃圾。

于 2013-11-05T17:50:39.493 回答
2

仅仅因为一个对象中有数据并不意味着它不会被垃圾收集。垃圾收集检查您是否持有对它的任何引用。如果您唯一的引用c是在您的链接列表中并且您将其删除,那么它将被垃圾收集。

于 2013-11-05T17:52:00.577 回答
1

c 不会被垃圾收集,因为 'current' 正在引用它。

当没有对它的实时引用时,可以对一个对象进行垃圾回收,但请记住,一个对象可以有多个对它的引用。

于 2013-11-05T17:48:04.587 回答