allpaths是一个List>在findPaths(...)方法中定义,该方法在其范围内调用dfs(...)方法,但我不明白为什么所有路径都会更新,因为它不是全局变量?那么,调用 dfs 方法后,所有路径列表是如何更新的呢?
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
这意味着字符串是按值传递的,列表是按引用传递的。
嗯,这就是所有原始数据类型(int,double,...)和引用之间的区别。 创建变量时,每次将此变量传递给其他方法时,都会复制其值。基元数据类型和引用之间的区别在于它们存储哪些值。
基元数据类型
直接存储值(例如数字)。传递变量时,将复制数字。
引用
当你处理对象时,你实际上处理了对对象的引用。存储对象的变量实际上存储对该对象的引用(如地址)。将此变量传递给另一个方法时,仅复制此对象的地址,这意味着两个方法在内存中使用完全相同的对象。
这就是为什么您使用 ints 的示例按预期工作的原因。如果你想实际克隆一个对象,你必须实现Cloneable
(java.lang.Cloneable
)接口。