2017-08-26 76 views
2

我有兩個ArrayList。我只想重用第二個ArrayList(temporaryArrayList)。請注意我的代碼。希望你當然會理解我想讓你知道的事情。有沒有什麼辦法重用java中的arraylist?

ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>(); 
    ArrayList<String> temporaryArrayList = new ArrayList<>(); 

    temporaryArrayList.add("I"); 
    temporaryArrayList.add("you"); 
    temporaryArrayList.add("he"); 
    temporaryArrayList.add("she"); 
    temporaryArrayList.add("we"); 

    arrayListContainer.add(temporaryArrayList); 

    temporaryArrayList.clear(); 

    temporaryArrayList.add("Rahim"); 
    temporaryArrayList.add("jon"); 
    temporaryArrayList.add("don"); 
    temporaryArrayList.add("shaila"); 

    arrayListContainer.add(temporaryArrayList); 
    temporaryArrayList.clear(); 


    System.out.println(arrayListContainer.size()); 

的代碼是給arrayListContainer的預期大小,但是沒有得到預期的結果爲

System.out.println(arrayListContainer.get(0).get(0)); 

我怎樣才能做到這一點。謝天謝地接受任何形式的回覆或建議。

+0

的另一種自然的方式,你在期待'的System.out.println(arrayListContainer.get(0)獲得(0));'爲你帶來? – d512

+0

爲什麼你想重新使用'temporaryArrayList'?正如答案指出的那樣,無論如何你都必須複製它。所以沒有任何儲蓄,只有更多的困惑。 – Thilo

+0

我需要一個類型arraylist的arraylist爲我的項目.. – Sadhon

回答

3

您正在添加相同的對象並將其刪除。 爲了不同溫度-列表添加到arrayListContainer你應該創建一個副本:

變化是做線:

arrayListContainer.add(temporaryArrayList); 

到:

ArrayList<String> copy = new ArrayList<>(temporaryArrayList) 
arrayListContainer.add(copy); 

另一種選擇,因爲蒂洛在下面的評論中建議每次都會創建一個新的temporaryArrayList,這樣你就可以確保將不同的臨時列表添加到arrayListContainer

+2

...或者只是不要重用temporaryArrayList。更乾淨。 – Thilo

2

您需要在添加它時創建ArrayList的克隆,否則當刪除內容時,您將刪除剛剛添加的實際列表的內容。克隆它將添加ArrayList的副本,而不是原始副本。

編輯:其實 - 基於對對方的回答蒂洛的評論 - 一個更好的解決辦法是臨時的ArrayList代碼提取到一個方法,並調用它:

public static void main(String[] args){ 

    ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>(); 

    String[] a = {"I","you","he"}; 
    arrayListContainer.add(createArrayList(a)); 
    String[] b = {"Bob","Rahim","Betty"}; 
    arrayListContainer.add(createArrayList(b)); 

    System.out.println(arrayListContainer.size()); 
    System.out.println(arrayListContainer.get(0).get(0)); 
} 

private static ArrayList<String> createArrayList(String[] arr) { 
    ArrayList<String> temporaryArrayList= new ArrayList<>(); 
    for(String str : arr) { 
     temporaryArrayList.add(str); 
    } 
    return temporaryArrayList; 
} 
1

你不能在重複使用你想要的方式。您的ArrayList<ArrayList<String>>包含參考到對象(​​在這種情況下,參考ArrayList<String>)。如果你說

arrayListContainer.add(temporaryArrayList); 

後來,

arrayListContainer.add(temporaryArrayList); 

之間沒有分配一個新的價值temporaryArrayList,你arrayListContainer將有兩個引用同一個對象。 temporaryArrayList是對象的引用,即使對象的內容發生變化(除非您重新分配一個全新的對象),它也不會改變。

您需要創建一個新對象。

1

你的情況,你不需要數組列表數組列表,只讓字符串數組的數組列表:

ArrayList<String[]> arrayContainer = new ArrayList<>(); 

添加完字符串,請致電:

arrayContainer.add(temporaryArrayList.toArray(new String[temporaryArrayList.size()])); 

這樣你可以安全地重用臨時數組列表。

2

其他答案是正確的。你重複使用你的第二個ArrayList,而不是你想要的方式。

您需要了解(a)對對象的引用,以及(b)ArrayList是一個對象,該對象是對其他對象的引用的容器。

讓我們看看代碼執行期間的狀態。

首先實例化一個ArrayList,其默認值爲10個插槽。將持有對引用String對象的其他ArrayList實例的引用。

ArrayList< ArrayList<String> > arrayListContainer = new ArrayList<>(); 

enter image description here

ArrayList<String> temporaryArrayList = new ArrayList<>() ; 

enter image description here

String實例化對象,添加在我們的第二列表中的狹槽的每一個參考。請記住,該列表包含參考String對象,而不是對象本身。

temporaryArrayList.add("I") ; 
temporaryArrayList.add("you") ; 
temporaryArrayList.add("he") ; 
temporaryArrayList.add("she") ; 
temporaryArrayList.add("we") ; 

enter image description here

到第二列表添加一個參考第一列表的第一時隙。

arrayListContainer.add(temporaryArrayList) ; 

enter image description here

通過調用clear()刪除對String對象與代詞的所有引用。這些String對象實際上在內存中存在了一段時間,因此成爲垃圾收集的候選對象,因爲它們未被任何其他對象引用。所以我們在這個圖表中顯示它們已經消失了,但實際上它們可能會在內存中浮動一段時間。

temporaryArrayList.clear() ; 

enter image description here

實例化一些新String對象。在第二個列表的插槽中提供每個參考。

temporaryArrayList.add("Rahim") ; 
temporaryArrayList.add("jon") ; 
temporaryArrayList.add("don") ; 
temporaryArrayList.add("shaila") ; 

enter image description here

這是你的誤會出現的地方。你顯然想要保留代詞並在他們旁邊添加一些專有名稱。但第一個列表不包含對String對象的引用,它保存對String對象的ArrayList的引用。因此,我們最終得到了兩個對包含對專有名稱字符串的引用的對象ArrayList的引用。舊的代詞字符串可能會或可能不會在記憶中浮動,但我們無法再接觸到它們,所以我們認爲它們已經消失。

arrayListContainer.add(temporaryArrayList) ; 

enter image description here

下一頁清除字符串的一個且唯一的列表。所以現在第一個ArrayList持有兩個引用到現在空的第二個ArrayList

temporaryArrayList.clear() ; 

enter image description here

你結束了,其中每個元素是指向同一個空「臨時」列表中的兩個元素的一個列表。

如果您想積累第一個列表中的字符串,請將第一個列表重新定義爲StringArrayList而不是ArrayList<String>。所以,與其這樣:

​​

...這個,改變addaddAll

ArrayList<String> arrayListContainer = new ArrayList<>() ; 
ArrayList<String> temporaryArrayList = new ArrayList<>() ; 
… 
arrayListContainer.addAll(temporaryArrayList) ; // Call `addAll` to add the elements of one collection to another collection. 

提示:儘可能使用接口。

通常最好指定更通用的接口而不是具體的類,以便您可以更輕鬆地切換出具體的類;所以你可以使用ListList< List<String> >

List<List<String>> listContainer = new ArrayList<>(); 
1
ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>(); 
    ArrayList<String> temporaryArrayList = new ArrayList<>(); 

    temporaryArrayList.add("I"); 
    temporaryArrayList.add("you"); 
    temporaryArrayList.add("he"); 
    temporaryArrayList.add("she"); 
    temporaryArrayList.add("we"); 

    arrayListContainer.add(new ArrayList<>(temporaryArrayList)); 

    temporaryArrayList.clear(); 

    temporaryArrayList.add("Rahim"); 
    temporaryArrayList.add("jon"); 
    temporaryArrayList.add("don"); 
    temporaryArrayList.add("shaila"); 

    arrayListContainer.add(new ArrayList<>(temporaryArrayList)); 
    temporaryArrayList.clear(); 


    System.out.println(arrayListContainer.get(0).get(0)); 

這是克隆的對象:)

相關問題