当Java ArrayList作为参数传递给返回void并在函数中修改的函数时,它是如何修改的?可能会混淆传递值

当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

我有一段Java代码,它通过将ArrayList传递到一个方法、修改该方法中的列表并返回void来修改ArrayList。我认为Java的pass-by值会导致原始ArrayList不会被修改。我误解了什么

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”返回类型与方法参数在方法中的使用方式无关,我不确定您为什么会这样想。这应该