2017-02-15 40 views
-1

編輯:JAVA:爲什麼我需要建立在這個函數一個新的列表對象?

功能是回答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; 
    } 

    ... 
} 

可能有人給我講解一下?謝謝!

+5

區別正是你所說的。要麼你正在創建一個新的列表,或者你正在使用現有的列表。這個功能的意圖是什麼? – CollinD

+0

意圖是將「列表」添加到「結果」,該函數是lintcode問題答案的一部分。但是,當我使用第二個版本時,輸出是[[],...,[]],基本上所有的內部列表都是空的。如果我切換到第一個,它會起作用。這就是爲什麼我有點困惑 –

+0

你能否提供解決方案的組合和問題的實現? – Brion

回答

1

當創建通過使現有列表給構造包含在列表中的一個整數新ArrayList對象是複製到該新的列表。

如果該列表僅僅被添加到結果中並且之後被例如添加或刪除元素的修改反映在可能或可能不需要的結果中,具體取決於上下文。

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]] 
} 

在此,首先兩個列表被添加到每個含有一個整數的結果:運行此代碼時

的差別變得很明顯。第一個列表使用helper1添加,第二個列表使用helper2添加。之後,通過添加另一個Integer來修改這兩個列表。對於list1,這個改變對我們的結果沒有任何影響,但是對list2的修改卻沒有影響。

+0

謝謝!這正是問題所在。 –

0

最終,他們正在做同樣的事情,但是,我可以看到,唯一的區別是第一個使用更多的內存並沒有必要真正構建一個已經存在的一個新的ArrayList。

0

在第一個例子,你真的鴕鳥政策使用給定值,而不是創建新的本地列表。 在第二個例子中,你與給定值工作。

例如,如果您調用該方法並給出ArrayList<Integer>list[2,5,52,888]的值,則您將該值添加到現有列表中。

0

在第二個例子中,如果列表的方法之外改變在結果列表中也發生了變化,因爲它是名單的同一個實例。

在第一個例子中,你創建列表,從修改隔離它的副本。

+0

謝謝!你很重要。 –

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的(列表)的構造函數的值的副本列表中的新對象。第二種方法簡單地將參考列表添加到稍後在我給出的示例項目中使用的數組中,現在您有兩種不同的方式來訪問list1。

+0

非常感謝你的回答。這真的很有幫助! –

相關問題