首页 > 解决方案 > 为什么列表即使按值传递也会更新?

问题描述

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。

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

标签: javadata-structureslinked-listoutputsingly-linked-list

解决方案


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

在第二次迭代datanode2(= temp) 将递增,并temp移动到temp.nextis null

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

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

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


推荐阅读