为什么List <List <Integer >>即使不是全局变量也要更新?

时间:2019-08-10 17:15:21

标签: java methods global-variables

allpaths是在findPaths(...)方法中定义的List>,该方法在其范围内调用dfs(...)方法,但是我不明白为什么allpaths不是全局变量,所以为什么要对其进行更新?那么,调用dfs方法后allpaths List如何更新?

import java.util.*;

class TreeNode {
  int val;
  TreeNode left;
  TreeNode right;

  TreeNode(int x) {
    val = x;
  }
};

class FindAllTreePaths {
  public static List<List<Integer>> findPaths(TreeNode root, int sum) {
    List<List<Integer>> allpaths = new ArrayList<List<Integer>>();
    List<Integer> cpath = new ArrayList<Integer>();
    dfs(root, sum, cpath, allpaths);
    return allpaths;
  }
  private static void dfs(TreeNode root, int sum, List<Integer> cpath, List<List<Integer>> result){
    if(root == null){
      return;
    }
    if(root.val == sum && root.left == null && root.right == null){
      cpath.add(root.val);
      result.add(cpath);
    }
    List<Integer> temp = new ArrayList<Integer>();
    temp.addAll(cpath);
    temp.add(root.val);
    dfs(root.left, sum-root.val, temp, result);
    dfs(root.right, sum-root.val, temp, result);
  }

  public static void main(String[] args) {
    TreeNode root = new TreeNode(12);
    root.left = new TreeNode(7);
    root.right = new TreeNode(1);
    root.left.left = new TreeNode(4);
    root.right.left = new TreeNode(10);
    root.right.right = new TreeNode(5);
    int sum = 18;
    List<List<Integer>> result = FindAllTreePaths.findPaths(root, sum);
    System.out.println("Tree paths with sum " + sum + ": " + result);
  }
}

此外,我尝试了以下代码,该代码是上述方案的缩放版本:

public class Main {
    public static void main(String[] args) {
        int c = call();
        System.out.println(c);
    }

    public static int call(){
        int c=100;
        call1(c);
        return c;
    }

    private static void call1(int d){
        c=4;
        d = 4;
    }
}

,结果是: c = 100

这表明c对于call1()而言不是全局的。

编辑: 我试过下面的代码,因为有人告诉我引用类型变量是按引用传递的,但这不是正确的:

public class Main {
    public static void main(String[] args) {
        call();
    }

    public static void call(){
        String c="Jack";
        List<Integer> l = new ArrayList<Integer>();
        l.add(1);
        call1(c, l);
        System.out.println(c);
        System.out.println(l.get(0) + " " + l.get(1));
    }

    private static void call1(String c, List<Integer> l){
        l.add(2);
        c="Jack Ryan";
    }
}

但是输出是: 插口 1 2

这意味着String通过值传递,而List通过引用传递。

1 个答案:

答案 0 :(得分:1)

好吧,这就是所有原始数据类型(int,double,...)和引用之间的区别。 创建变量时,每次将此变量传递给另一个方法时,它的值都会被复制。原始数据类型和引用之间的区别在于,它们存储哪些值。

原始数据类型

直接存储值(例如数字)。当您传递变量时,数字将被复制。

参考

在处理对象时,实际上是在处理对对象的引用。一个存储对象的变量实际上存储了对该对象的引用(例如地址)。当您将此变量传递给另一个方法时,仅复制该对象的地址,这意味着这两个方法在内存中使用的对象完全相同。

这就是为什么您使用int的示例可以按预期工作的原因。如果要克隆对象,则必须实现arr[i] = (arr[i] % 256) * 65536; Cloneable)接口。