java - 为什么列表即使按值传递也会更新?
问题描述
public class Node<T> {
T data;
Node<T> next;
Node(T data){
this.data = data;
}
}
public class LinkedListUse{
public static void print(Node<Integer> head){
Node<Integer> temp = head;
while(temp != null){
System.out.print(temp.data +" ");
temp = temp.next;
}
System.out.println();
}
public static void increment(Node<Integer> head){
Node<Integer> temp = head;
while(temp != null){
temp.data++;
temp = temp.next;
}
}
public static void main(String args[]){
Node<Integer> node1 = new Node<Integer>(10);
Node<Integer> node2 = new Node<Integer>(20);
node1.next = node2;
increment(node1);
print(node1);
}
}
由于node1
在函数中通过值传递(而不是通过引用传递)increment
,因此根据我的输出应该是 10 20,但解决方案是 11 21。
你能帮我解释一下这背后的原因吗
解决方案
调用increment
将改变列表。也许它有助于可视化列表。执行后node1.next = node2
我们得到这样的情况:
node1 node2
↓ ↓
┌───────────┐ ┌───────────┐
│ data: 10 │ │ data: 20 │
│ next: ──────> │ next: null│
└───────────┘ └───────────┘
然后increment(node1)
将定义另外两个引用的变量node1
:
head
temp
node1 node2
↓ ↓
┌───────────┐ ┌───────────┐
│ data: 10 │ │ data: 20 │
│ next: ──────> │ next: null│
└───────────┘ └───────────┘
在其while
循环中,它将首先递增temp.data
(因此变为 11),然后将temp
引用移动到node2
:
head temp
node1 node2
↓ ↓
┌───────────┐ ┌───────────┐
│ data: 11 │ │ data: 20 │
│ next: ──────> │ next: null│
└───────────┘ └───────────┘
在第二次迭代data
中node2
(= temp
) 将递增,并temp
移动到temp.next
is null
:
head temp==null
node1 node2
↓ ↓
┌───────────┐ ┌───────────┐
│ data: 11 │ │ data: 21 │
│ next: ──────> │ next: null│
└───────────┘ └───────────┘
因此,尽管对 的更改temp
不会影响对 的引用,但对被引用节点node1
的任何突变都将保留,即使在对 的调用完成执行之后也是如此。不再有 10 的值,也没有 20。这些已被覆盖。increment
调用该print
方法时,会发生与调用时类似的事情increment
,只是现在没有给节点带来突变。它将找到调用increment
. 没有其他节点。
推荐阅读
- epplus - 来自类成员的 Epplus LoadFromCollection 标头
- google-apps-script - Google 表单响应提交和 Google 表格更新
- python - 如何在 BeautifulSoup4 中刮掉结束标签旁边的文本?
- google-apps-script - 需要将列表中的一个值转换为另一个值
- java - 覆盖 jar 中的属性文件
- c++ - CLion:构建程序不会在 cmd 中运行
- python - TypeError:“AnchorLayout”对象不可调用 kivy python
- swift - 打开应用程序时如何关注文本字段?
- php - 在 php 的集合中添加参数
- tensorflow - TF Eager 预训练模型