我正面临java中引用的概念问题。这是我实现的一个基本的LinkedList
:
节点:
class Node {
int data;
Node next = null;
public Node(int data) {
this.data = data;
}
}
列表:
class LinkedList {
Node n = null;
Node start = null;
int flag = 0;
void insertion(int x) {
if(flag==0)
{
Node newnode = new Node(x);
n = newnode;
start = newnode;
flag = 1;
return;
}
Node newnode = new Node(x);
n.next = newnode;
n = n.next;
}
void deletion() {
Node str = start;
while(str.next.next != null)
str = str.next;
str.next = null;
}
void printlist() {
Node str = start;
while(str != null) {
System.out.println(str.data);
str = str.next;
}
}
}
测试类:
public class Test31 {
public static void main(String[] args){
LinkedList ll = new LinkedList();
ll.insertion(5);
ll.insertion(15);
ll.insertion(25);
ll.insertion(35);
ll.insertion(45);
ll.insertion(55);
ll.deletion();ll.deletion();
ll.printlist();
}
}
上面的程序工作得很好,没有任何问题,但是如果我用这段代码替换deletion()
:
void deletion() {
Node str = start;
while(str.next != null)
str = str.next;
str = null;
}
则不删除元素。我很想知道为什么会这样。使用str.next.next
的技巧,但如果我使用上面给出的删除方法,它不应该也达到同样的效果,只是一个迭代的while循环?
这是因为其中一个str.next
对象仍然有对它的引用(或者可能start
正在引用它)。通过将str
设置为null,您只是将该方法中的局部变量设置为null
,但是通过将str.next
设置为null,您正在删除该str
对象中的引用。
简单的例子:
Node start = new Node();
Node another = new Node();
start.next = another;
Node toDelete = another;
如果你这样做:
toDelete = null;
在这种情况下,toDelete
现在是null
。start.next
和another
仍然包含对another
最初赋值对象的引用。即使你附加了这个:
another = null;
在这种情况下,还剩下一个引用。start.next
仍然指向another
最初被赋值的原始对象。
我认为第一个删除方法实际上也是不正确的,因为它永远不会删除开始节点,如果你只有一个节点,它会抛出NullPointerException
,因为start.next
是null
, while循环试图到达start.next.next
。我认为这样更准确:
void deletion() {
Node parent = null;
Node current = start;
while (current.next != null) {
parent = current;
current = current.next;
}
if (parent == null) {
start = null;
flag = 0;
} else {
parent.next = null;
n = parent;
}
}