当Java ArrayList作为参数传递给返回void并在函数中修改的函数时,它是如何修改的?可能会混淆传递值
我有一段Java代码,它通过将ArrayList传递到一个方法、修改该方法中的列表并返回void来修改ArrayList。我认为Java的pass-by值会导致原始ArrayList不会被修改。我误解了什么当Java ArrayList作为参数传递给返回void并在函数中修改的函数时,它是如何修改的?可能会混淆传递值,java,recursion,arraylist,pass-by-value,Java,Recursion,Arraylist,Pass By Value,我有一段Java代码,它通过将ArrayList传递到一个方法、修改该方法中的列表并返回void来修改ArrayList。我认为Java的pass-by值会导致原始ArrayList不会被修改。我误解了什么 public class Question { public static void weaveLists(LinkedList<Integer> first, LinkedList<Integer> second, ArrayList<LinkedL
public class Question {
public static void weaveLists(LinkedList<Integer> first, LinkedList<Integer> second, ArrayList<LinkedList<Integer>> results, LinkedList<Integer> prefix) {
/* One list is empty. Add the remainder to [a cloned] prefix and
* store result. */
if (first.size() == 0 || second.size() == 0) {
LinkedList<Integer> result = (LinkedList<Integer>) prefix.clone();
result.addAll(first);
result.addAll(second);
results.add(result);
return;
}
/* Recurse with head of first added to the prefix. Removing the
* head will damage first, so we’ll need to put it back where we
* found it afterwards. */
int headFirst = first.removeFirst();
prefix.addLast(headFirst);
weaveLists(first, second, results, prefix);
prefix.removeLast();
first.addFirst(headFirst);
/* Do the same thing with second, damaging and then restoring
* the list.*/
int headSecond = second.removeFirst();
prefix.addLast(headSecond);
weaveLists(first, second, results, prefix);
prefix.removeLast();
second.addFirst(headSecond);
}
public static ArrayList<LinkedList<Integer>> allSequences(TreeNode node) {
ArrayList<LinkedList<Integer>> result = new ArrayList<LinkedList<Integer>>();
if (node == null) {
result.add(new LinkedList<Integer>());
return result;
}
LinkedList<Integer> prefix = new LinkedList<Integer>();
prefix.add(node.data);
/* Recurse on left and right subtrees. */
ArrayList<LinkedList<Integer>> leftSeq = allSequences(node.left);
ArrayList<LinkedList<Integer>> rightSeq = allSequences(node.right);
/* Weave together each list from the left and right sides. */
for (LinkedList<Integer> left : leftSeq) {
for (LinkedList<Integer> right : rightSeq) {
//This is the part I don't understand
ArrayList<LinkedList<Integer>> weaved = new ArrayList<LinkedList<Integer>>();
weaveLists(left, right, weaved, prefix);
result.addAll(weaved);
}
}
return result;
}
}
公开课问题{
公共静态void weaveLists(LinkedList第一,LinkedList第二,ArrayList结果,LinkedList前缀){
/*一个列表为空。将其余的添加到[克隆的]前缀中,然后
*存储结果*/
if(first.size()==0 | | second.size()==0){
LinkedList结果=(LinkedList)前缀.clone();
结果:addAll(第一);
结果:addAll(第二);
结果。添加(结果);
返回;
}
/*在前缀中添加头of first的情况下递归。删除
*头部首先会受损,所以我们需要把它放回我们需要的地方
*后来发现的*/
int headFirst=first.removeFirst();
前缀.addLast(headFirst);
weaveLists(第一、第二、结果、前缀);
prefix.removeLast();
first.addFirst(headFirst);
/*对第二个进行同样的操作,先破坏,然后恢复
*名单*/
int headSecond=second.removeFirst();
前缀addLast(头秒);
weaveLists(第一、第二、结果、前缀);
prefix.removeLast();
第二,添加第一(头秒);
}
公共静态ArrayList allSequences(TreeNode节点){
ArrayList结果=新建ArrayList();
if(node==null){
添加(新的LinkedList());
返回结果;
}
LinkedList前缀=新建LinkedList();
前缀.add(节点.data);
/*在左子树和右子树上递归*/
ArrayList leftSeq=所有序列(node.left);
ArrayList rightSeq=所有序列(node.right);
/*从左侧和右侧将每个列表编织在一起*/
for(LinkedList左:leftSeq){
for(LinkedList right:rightSeq){
//这是我不明白的部分
ArrayList weaved=新建ArrayList();
编织者(左、右、编织、前缀);
结果:addAll(编织);
}
}
返回结果;
}
}
我希望调用result.addAll(weaved)时不会修改weaved数组,但在调用weaveLists()后会修改weaved数组,即使它返回void。您创建了一个
weaved
对存储在内存中的ArrayList
对象的引用。当您调用new
操作符时,将在内存中分配一个新对象。然后将引用weaved
传递给weaveLists()
方法。
此方法有一个引用
结果
,但这只是一个引用内存中相同对象的引用,因为只有new
操作符分配一个新内存。因此,weaveLists()
方法将修改原始的ArrayList。这是您应该理解的一个主要功能,我建议您阅读按值传递和按引用传递之间的区别。您创建了一个编织的
引用,指向存储在内存中的数组列表
对象。当您调用new
操作符时,将在内存中分配一个新对象。然后将引用weaved
传递给weaveLists()
方法。
此方法有一个引用
结果
,但这只是一个引用内存中相同对象的引用,因为只有new
操作符分配一个新内存。因此,weaveLists()
方法将修改原始的ArrayList。这是您应该理解的一个主要特性,我建议您阅读按值传递和按引用传递之间的区别,简单地回答这个问题-您误解了按值传递在Java中的含义
如果传递对象(本例中为列表)并在不更改其引用的情况下操纵其元素,则该对象与传递的对象相同,对象(列表)本身没有任何更改,其引用与传递给函数时相同,但更改确实适用于任何被操纵的元素
在此上下文中,按值传递仅意味着,如果在函数中创建给定列表的新实例,然后对其进行操作,则不会对原始列表应用任何更改,因为这将作为局部变量而不是传递的变量进行观察
检查问题的顶部答案,或者只阅读一些与传递值相关的java基础知识。使用blog或其他您可能更喜欢的工具。简而言之,回答这个问题-您误解了传递值在Java中的含义 如果传递对象(本例中为列表)并在不更改其引用的情况下操纵其元素,则该对象与传递的对象相同,对象(列表)本身没有任何更改,其引用与传递给函数时相同,但更改确实适用于任何被操纵的元素 在此上下文中,按值传递仅意味着,如果在函数中创建给定列表的新实例,然后对其进行操作,则不会对原始列表应用任何更改,因为这将作为局部变量而不是传递的变量进行观察
检查问题的顶部答案,或者只阅读一些与传递值相关的java基础知识。使用blog或任何其他您可能更喜欢的方法。这应该会有帮助:,。“但是weaved数组在调用weaveLists()后会被修改,即使它返回void”返回类型与方法参数在方法中的使用方式无关,我不确定您为什么会这样想。这应该