簡體   English   中英

JAVA:為什么我需要在此函數中創建一個新的列表對象?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM