修改
该函数是lintcode问题“组合和”答案的一部分,如果我使用第二个版本,则输出为“[[],...,[]],其中所有内部列表为空,即使它们传递给了值。当我只是切换到第一个版本而不改变任何其他东西时,它会起作用。
所以我认为它与Java参数传递过程有关,我不明白。你能解释一下为什么只有第一个版本可以工作吗?
代码:
private void helper(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list, int target, ...) {
if (target == 0) {
result.add(new ArrayList<Integer>(list));
return;
}
...
}
问题:
为什么我需要创建一个新的 ArrayList 对象,然后将其添加到结果?
此方法与下面的代码有什么区别:
private void helper(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list, int target, ...) {
if (target == 0) {
result.add(list);
return;
}
...
}
有人可以向我解释一下吗?谢谢!
答案 0 :(得分:2)
通过将现有列表传递给构造函数来创建新的ArrayList对象时,列表中包含的整数将复制到该新列表。
如果仅将列表添加到结果中,并且之后通过例如修改列表进行修改。根据上下文,添加或删除元素,修改会反映在结果中,这些结果可能是也可能不是。
运行此代码时差异变得明显:
sudo vi /etc/sysconfig/selinux
这里,前两个列表被添加到每个包含一个Integer的结果中。使用helper1添加第一个列表,使用helper2添加第二个列表。之后,通过添加另一个Integer来修改两个列表。对于list1,更改对我们的结果没有任何影响,但list2的修改确实如此。
答案 1 :(得分:0)
最终,他们正在做同样的事情,但是,我能注意到的唯一区别是第一个使用更多内存,并且不需要实际构建已存在的新ArrayList。
答案 2 :(得分:0)
在第一个示例中,您实际上并未使用给定值,而是创建一个新的本地List。 在第二个示例中,您是否使用给定值。
例如,如果您调用该方法并将其作为ArrayList<Integer>list
[2,5,52,888]
的值,则将该值添加到现有列表中。
答案 3 :(得分:0)
在第二个示例中,如果在方法之外更改列表,则结果中的列表也会更改,因为它是列表的相同实例。
在第一个示例中,您将创建一个列表副本,将其与修改隔离开来。
答案 4 :(得分:0)
@CollinD提出了一个很好的问题,以确保你知道帮助方法的真正意图。
当您使用Java传入对象时,您将传入对象的引用。对引用的任何更改都将反映在您创建的原始对象中。
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> arrays = new ArrayList<>();
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
helper(arrays, list1);
arrays.get(0).add(3);
list1.forEach(e -> System.out.print(e));
System.out.print("\n");
arrays.get(0).forEach(e-> System.out.print(e));
}
尝试使用两种不同的辅助方法执行此示例代码。
您会注意到原始方法将为您提供两个不同的值列表。
12
123
虽然第二种方法为您提供相同的值
123
123
这是因为ArrayList(list)的构造函数将list中的值复制到新对象。第二种方法简单地将引用列表添加到稍后要使用的数组中,在我给出的示例项目中,您现在有两种不同的方式来访问list1。