java - 对象引用不影响它引用的对象?
问题描述
我对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;
该head
节点现在指向地址 100。并target
指向300。
在这之后,
target = target.deleteNode(target, target.data);
现在,if
上面指出的条件被执行并target
变为 400。没有实际删除发生。
现在,头节点仍然完好无损并打印整个列表。
例如,考虑以下内容。
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
希望我澄清了这个问题。
推荐阅读
- python - Django 序列化器显示相关模型的 BooleanField
- sql - 搜索表单以从两个不同的表中搜索和获取数据
- elasticsearch - elasticsearch.scroll() 显示命中,但如果滚动返回,则返回空结果
- java - 如何等待按钮内的加载程序完成加载?
- reactjs - 如何保护使用 Firebase 作为后端的反应应用程序中的路由
- jquery - 如何在单击复选框时获取文本框值
- machine-learning - 评估推荐系统的选项
- mediawiki - 如何在 MediaWiki 的主页上列出所有页面或类别?
- python-3.x - 读取带参数的文件
- python - 如何将两个字符串列表导出到 csv 文件中的两列而不分开