如何设置已经实例化为null的变量?

时间:2014-01-14 04:59:27

标签: java linked-list

嗨大家我正在用Java做一些测试。

请参阅方法deleteMiddleNode(),该方法应该在给定节点的情况下将其删除在链表中。 除了我想删除最后一个节点的情况外,这一切都正常。 我所做的是将最后一个节点设置为null,如果那是要删除的节点(请参阅注释)。它并没有真正起作用,s5仍然有其价值。

当我只想重置key的{​​{1}}属性时,它确实有用。

我想知道为什么它会像这样。

s5

public class Three {
    static SinglyNode s5 = new SinglyNode(5);

    public static void main(String[] args) {
        SinglyNode s1 = new SinglyNode(1);
        SinglyNode s2 = new SinglyNode(2);
        SinglyNode s3 = new SinglyNode(3);
        SinglyNode s4 = new SinglyNode(4);

        s1.next = s2;
        s2.next = s3;
        s3.next = s4;
        s4.next = s5;
        deleteMiddleNode(s5);

        SinglyNode ptr = s1;
        while (ptr!= null) {
            System.out.print(ptr.key+" ");
            ptr = ptr.next;
        }
    }

    // this method is wrong
    public static boolean deleteMiddleNode(SinglyNode node){
        if (node == null) {
            return false;
        }
        if (node.next == null) { // last node

    /*  this part does work 
            System.out.println(node.key);
            node.key = 222;
            System.out.println(s5.key);                                    
    */

            node = null; // but this doesn't set the last node to null.

            return true;
        }
        node.key = node.next.key;
        node.next = node.next.next;
        return true;
    }

}

3 个答案:

答案 0 :(得分:1)

Java 按值传递

这意味着变量保存引用值(就像C中的指针一样),当您将它们传递给方法时,该值将被复制到方法内的局部变量中。更改局部变量包含的内容(例如,将其设置为null)不会影响该方法之外的任何内容。

在您的示例中,您的方法签名是:

deleteMiddleNode(SinglyNode node)

当您从main调用deleteMiddleNode(s5)时,s5中包含的参考值将复制到您方法中的node

答案 1 :(得分:1)

假设您有一个链接节点列表:A - > B - > C - > D - >即

要从链表中删除节点C,您需要找到链接到C的节点,在本例中为B,并将其目标节点更改为D(以前用于链接的C)。

然后,由于C没有被任何人引用,它最终将被垃圾收集。

因此,在您的示例中,要删除s5,您需要将s4的.next属性设置为null,从而指示链接列表在s4结束。

由于您始终保留对列表中第一项的引用,如果您要删除此第一项,只需将其“第一项引用”替换为其.next引用。

答案 2 :(得分:0)

如评论中所述,Java通过 value 传递参数,而不是通过 reference 传递参数。因此,在node中将null设置为deleteMiddleNode会将本地变量(参数变量)设置为null,但不会将您传递的变量设置为null来电者。

您需要在调用代码中将其设置为node

另一种方法是将要删除的节点(previous)及其前一个节点(previous.next)传递给该方法,然后将node.next设置为node从链中删除节点(null本身不必设置为null,因为它将被垃圾收集。设置为{{1}}不影响这个) 。然后,当您丢失列表中的“入口点”时,您需要对第一个节点进行特殊处理。