对象引用不影响它引用的对象



我对Java的理解是,如果对同一个对象有两个引用,在一个引用下对对象状态所做的任何更改都将反映在另一个引用中。以两个List引用为例(为了简单起见,省略了泛型(。

List list = Arrays.asList(1, 2, 3, 4, 5);
List list2 = list;
list2.set(0, 17);
System.out.println(list); //prints [17, 2, 3, 4, 5]

正如预测的那样,修改list的内容对list2具有相同的效果,因为它们都引用了相同的list对象。然而,我在这里得到了意想不到的结果。

Node head = new Node(0);
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
for(int number: numbers) head.appendToTail(number);
head.printNode(); //prints 0 1 2 3 4 5 6 7 8 9
Node target = head.next.next;
target = target.deleteNode(target, target.data);
head.printNode(); //prints 0 1 2 3 4 5 6 7 8 9

target是head.next.next中Node对象的引用,因此删除它本应消除Node 2,但它没有。但是,将最后三行替换为以下代码。

head.next.next = head.next.next.deleteNode(head.next.next, head.next.next.data);
head.printNode(); //prints 0 1 3 4 5 6 7 8 9

当然,这要乏味得多,所以我宁愿使用目标引用。为什么会发生这种情况?您可能不需要它,但我会在下面包含我的Node类,以防万一。

class Node {
Node next = null;
int data;
public Node(int d) {
data = d;
}

void printNode() {
Node n = this;
while (n != null) {
System.out.print(n.data + " ");
n = n.next;
}
System.out.println();
}
void appendToTail(int d) {
Node end = new Node(d);
Node n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
}
Node deleteNode(Node head, int d) {
if (head == null) return null;
Node n = head;
if (n.data == d) {
return head.next;
}
while (n.next != null) {
if (n.next.data == d) {
n.next = n.next.next;
return head;
}
n = n.next;
}
return head;
}
}
是的,它不会影响您的代码。

请考虑deleteNode函数中的这个片段。

if (n.data == d) {
return head.next;
}

考虑地址为100->200->300->400->500->。。

所以,现在我们有

Node target = head.next.next;

CCD_ 2节点现在指向地址100。CCD_ 3指向300。

之后,

target = target.deleteNode(target, target.data);

现在,执行上面指出的if条件,并且target变为400。没有实际删除。

现在,head节点仍然完好无损,并打印整个列表。

以下面的例子为例。

target = target.deleteNode(target, target.next.data);
head.printNode(); //prints 0 1 2 4 5 6 7 8 9

因此,您的第一个节点删除逻辑实际上删除了节点,但它只是返回第二个节点。

如果您想更改原始列表

head.next.next = target.deleteNode(target, target.data);
head.printNode(); // prints 0 1 3 4 5 6 7 8 9 

希望我澄清了这个问题。

相关内容

最新更新