【问题标题】:Why is the list updated even when it is passed by value? [duplicate]为什么列表即使按值传递也会更新? [复制]
【发布时间】:2021-08-05 12:12:27
【问题描述】:
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。

你能帮我解释一下这背后的原因吗

【问题讨论】:

  • 在Java中,一切都是按值传递的,但是传递的是什么值呢?在对象的情况下是参考。所以很明显,当有引用时,对象的属性是可以改变的。
  • 这能回答你的问题吗? Is Java "pass-by-reference" or "pass-by-value"?
  • 非常一般的建议:这类问题通常通过放置程序的中间输出来解决。在代码中间添加System.out.println(...),看看发生了什么。
  • @LuisA.Florit:如果混淆是关于传递引用的确切性质,那只会加深混淆。他们必须尝试纠正他们对传递引用本质的误解(并且重复的问题有一些很好的答案可以帮助解决这个问题)。

标签: java data-structures linked-list output singly-linked-list


【解决方案1】:

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│
└───────────┘   └───────────┘

在第二次迭代中,node2(=temp)的data 将递增,temp 移动到temp.next,即null

 head                             temp==null 
 node1           node2
  ↓               ↓
┌───────────┐   ┌───────────┐
│ data: 11  │   │ data: 21  │
│ next: ──────> │ next: null│
└───────────┘   └───────────┘

因此,尽管对temp 的更改不会影响对node1 的引用,但对引用节点 的任何更改都将保留,即使在对increment 的调用完成执行之后也是如此。不再有 10 的值,也没有 20。这些已被覆盖。

当调用print 方法时,会发生与调用increment 时类似的事情,只是现在没有给节点带来突变。它将找到调用increment 留下的节点。没有其他节点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 2023-03-20
    • 2013-02-12
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多