英文:
Is adding list in List of Lists added by reference?
问题
我试图理解Java对象引用。到目前为止我学到的是:
- 对象的引用是按值传递的,因此在该对象中添加的内容在方法返回后仍然可用。
- 在一个方法中创建一个新的对象 foo,该方法接收对象 foo 作为参数,将不会反映在本地创建的 foo 对象上对传递的 foo 对象所做的更改。
基于这个知识,我试图理解为什么以下代码片段没有从当前列表中移除已添加到结果列表的对象。
尽管下面的代码将 currentList 的引用添加到 resultList 中,而且我们正在从 currentList 中移除元素,但在递归结束时列表并没有为空。
findCombations(condidates, 0, target, new ArrayList<Integer>(), result);
public void findCombinations(int[] candidates, int index, Int target, List<Integer> currentList, List<List<Integer>> result) {
if(target == 0) {
result.add(currentList);
return;
}
if(target < 0) {
return;
}
for(int i = index; i < candidates.length; i++) {
if(i == index && candidates[i] != candidates[i - 1]) {
currentList.add(candidates[i]);
findCombinations(candidates, i + 1, target - candidates[i], currentList, result);
currentList.remove(currentList.size() - 1); //为什么从这个列表中移除数字不会移除已添加到结果列表的 currentList 中的数字?
}
}
}
可以有人帮助我理解这种行为吗?
编辑:
这是一个LeetCode问题,需要找到导致目标的唯一组合:
我们必须找到所有导致给定目标的唯一数字组合。我们不能有重复的集合/组合。提供的代码在给定数组上进行DFS,根据在数组中遇到的元素进行组合。有两个基本情况,当目标==0时,我们只需将 currentList 添加到 resultList 中。currentList 包含使和等于目标的数字,另一个基本情况是如果 target < 0,这种情况下,我们结束递归。
输入:candidates = [10,1,2,7,6,1,5],target = 8,
解集如下:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
英文:
I'm trying to understand java object references. What I learned so far is
- Objects' references are passed by value, so adding something in that object will be available in the object after the method returns.
- Creating a new object foo inside a method that received the object foo as argument will not reflect changes made on locally created foo object, on passed foo object.
Based on this knowledge, I'm trying to understand why the following code snippet isn't removing objects from current list that've been added to result list.
The code below doesn't suffer from empty list at the end of recursion even though it's adding references of currentList to resultList & we're removing elements from currentList.
findCombations(condidates, 0, target, new ArrayList<Integer>(), result);
public void findCombinations(int[] candidates, int index, Int target, List<Integer> currentList, List<List<Integer» result) {
if(target == 0) {
result.add(currentList);
return;
}
if(target < 0) { return; }
for(int i = index; i < candidates.length; i++) {
if(i == index && candidates[i] != candidates[i - 1]) {
currentList.add(candidates[i]);
findCombinations(candidates, i + 1, target - candidates[i], currentList, result);
currentList.remove(currentList.size() - 1); //why removing numbers from this list not removing the numbers from the currentList that's been added to result list?
}
}
Can someone please help me understand this behavior?
EDIT:
This is a leetcode question that requires unique combinations that lead to target:
We've to find all the unique number combinations whose sum lead to the given target. We can't have duplicate sets/combinations.
The provided code is doing DFS on the given array & finding the combinations based on subtracting an element that it comes across in the array. There are 2 base cases, when the target == 0, we just add the currentList in resultList. CurrentList contains the numbers whose sum == target & the other base case is if target < 0, in that case, we end recursion.
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
答案1
得分: 0
是的,是这样的。方法调用result.add(currentList)
会将对currentList
的引用添加到result
列表中。在此之后,您对currentList
所做的任何更改也将通过"result"可见,因为它持有对同一对象的引用。
简化示例:直观地说,您可能认为这个程序应该打印出[[“hello”],[]]
,但实际上它打印出[[], []]
,因为result
对同一列表实例持有两个引用。
List<List<String>> result = new ArrayList<>();
List<String> currentList = new ArrayList<>();
currentList.add("hello");
result.add(currentList);
currentList.remove(0);
result.add(currentList);
System.out.println(result);
如果您想阻止这种情况发生,可以在将其添加到result
时创建currentList
的副本。
// 添加一个副本,而不是对同一列表的引用
result.add(new ArrayList<>(currentList));
英文:
> Is adding list in List of Lists added by reference?
Yes, it is. The method call result.add(currentList)
adds a reference to currentList
to the result
list. Any changes that you make to currentList
after this point will be seen also through "result," because it holds a reference to the same object.
Simplified example: intuitively you might think this program should print [["hello"], []]
but instead it prints [[], []]
because result
holds two references to the same instance of list.
List<List<String>> result = new ArrayList<>();
List<String> currentList = new ArrayList<>();
currentList.add("hello");
result.add(currentList);
currentList.remove(0);
result.add(currentList);
System.out.println(result);
If you want to stop this from happening, you can create a copy of currentList
when you add it to result
.
// add a copy instead of a reference to the same list
result.add(new ArrayList<>(currentList));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论