[英]JAVA: Why do I need to create a new list object in this function?
編輯:
該函數是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對象,然后將其添加到result中 ?
此方法與以下代碼有什么區別:
private void helper(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list, int target, ...) {
if (target == 0) {
result.add(list);
return;
}
...
}
有人可以向我解釋嗎? 謝謝!
通過將現有列表傳遞給構造函數來創建新的ArrayList對象時,列表中包含的Integer將復制到該新列表。
如果只是將列表添加到結果中,然后通過例如添加或刪除元素進行修改,則根據上下文,修改可能會反映在結果中,這可能是預期的,也可能是預期的。
運行此代碼時,區別變得明顯:
private static void helper1(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list) {
// add by duplicating the provided list
result.add(new ArrayList<Integer>(list));
}
private static void helper2(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list) {
// add provided list as is
result.add(list);
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(10);
helper1(result, list1);
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(20);
helper2(result, list2);
System.out.println(result); // [[10], [20]]
list1.add(11);
list2.add(21);
System.out.println(result); // [[10], [20, 21]]
}
在此,將前兩個列表添加到結果中,每個列表包含一個Integer。 第一個列表使用helper1添加,第二個列表使用helper2添加。 之后,通過添加另一個Integer修改兩個列表。 對於list1,更改對我們的結果沒有任何影響,但對list2的修改卻有影響。
最終,他們在做同樣的事情,但是,我能注意到的唯一區別是第一個使用了更多的內存,並且不需要實際構造一個已經存在的ArrayList。
在第一個示例中,您實際上並沒有使用給定的值,而是創建了一個新的本地List。 在第二個示例中,您是否使用給定值。
例如,如果調用該方法並給定ArrayList<Integer>list
[2,5,52,888]
的值,則將其添加到現有List中。
在第二個示例中,如果在方法之外更改了列表,則結果中的列表也會更改,因為它是list的相同實例。
在第一個示例中,您將創建一個列表副本,將其與修改隔離。
@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的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.