【问题标题】:why assign ArrayList to new ArrayList temp为什么将 ArrayList 分配给新的 ArrayList temp
【发布时间】:2014-06-05 14:09:31
【问题描述】:

我正在查看 leetcode 上排列问题的代码。例如, [1,2,3] 有以下排列: [1,2,3]、[1,3,2]、[2,1,3]、[2,3,1]、[3,1,2] 和 [3,2,1]。 我发现有一句话

ArrayList<Integer> temp = new ArrayList<Integer>(l);

我不知道为什么这里需要将“l”分配给“temp”。我尝试了 current.add(l) 直接但给了我错误的答案。你能帮我解决这个问题吗?

public class Solution {

    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();

        //start from an empty list
        result.add(new ArrayList<Integer>());

        for (int i = 0; i < num.length; i++) {
            //list of list in current iteration of the array num
            ArrayList<ArrayList<Integer>> current = new ArrayList<ArrayList<Integer>>();

            for (ArrayList<Integer> l : result) {
                // # of locations to insert is largest index + 1
                for (int j = 0; j < l.size()+1; j++) {
                    // + add num[i] to different locations
                    l.add(j, num[i]);
                    ArrayList<Integer> temp = new ArrayList<Integer>(l);

                    current.add(temp);

                    //System.out.println(temp);

                    // - remove num[i] add
                    l.remove(j);
                }
            }

            result = new ArrayList<ArrayList<Integer>>(current);
        }

        return result;
    }
}

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    我不知道为什么这里需要将“l”分配给“temp”

    他不是——那只是:

    ArrayList<Integer> temp = l;
    

    相反,代码会在新的ArrayList 中创建l 引用的列表内容的副本。这意味着将来对 l 所指列表的更改(例如随后立即调用 l.remove(j))不会影响新列表。

    作为一个简单的独立示例,请考虑:

    List<String> original = new ArrayList<>();
    original.add("foo");
    List<String> copy = new ArrayList<>(original);
    System.out.println(copy.size()); // 1
    original.add("bar");
    System.out.println(copy.size()); // Still 1
    

    诚然,代码是以一种非常奇怪的方式编写的——直到最后一条语句,result 只有一个元素,所以迭代它是毫无意义的——但我相信这可以解释你所询问的单一语句。

    【讨论】:

    • 所以创建“temp”是为了避免进一步修改“l”。因此,如果没有“l.remove(j)”,我仍然可以写成“current.add(l)”,对吧?这就解释了“添加”方法只是将引用而不是对象复制到 ArrayList 中,对吗?
    • @Qiang:你的评论不是很清楚,但我怀疑你现在的想法是对的。
    • 谢谢你的好意。我为此苦苦挣扎了很久:)
    • 呃....抱歉又打扰你了。但是我遇到了一个新问题。因为“add”方法是调用 ArrayList“current”的引用“temp”。但是,在下一次迭代中。 temp 指向另一个新对象。这不会改变之前添加的“temp”吗?
    • @Qiang:再说一次,我不明白您的评论 - 但我建议您将其作为一个新的、单独的问题提出,并提供一个简短但完整的示例来说明问题。
    【解决方案2】:

    如果你这样做了

    current.add(l);
    

    您将向ArrayList l 添加相同的引用current。因此,如果您在其中一个列表中进行了一些更改,那么两者都会被修改。为了避免这个问题,在行中

    ArrayList<Integer> temp = new ArrayList<Integer>(l);
    

    您正在创建一个不同的ArrayList,但内容相同。因此,它们将是不同的对象(不同的引用)。

    【讨论】:

    • 感谢您的回答。我知道我在哪里犯了错误。 “添加”方法只是将引用而不是对象复制到 ArrayList。所以对“l”的进一步修改会影响“当前”。
    猜你喜欢
    • 2012-06-15
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 2015-08-11
    • 2018-08-16
    • 1970-01-01
    相关资源
    最近更新 更多