2011-03-30 83 views
1

說我有下面的代碼,簡單的Java問題ArrayList的元素

LinkedList partials = new LinkedList(); 
partials.add(new ArrayList()); 
ArrayList head = partials.element(); 
head.add("Test"); 

我想要的「頭」來簡單地ArrayList中的副本是partials.element的結果()。但是,現在,當我對「頭」進行更改時,它反映在Arraylist部分中。我該如何製作Arraylist的副本,這是部分片段的第一個元素,使得對Arraylist的更改不會反映在部分片段中?

回答

7

兩個選項浮現在腦海中:

  • 調用ArrayList構造這需要另一個集合 - 這會讓副本
  • 呼叫clone()ArrayList

注意,這兩個將創建副本 - 每個列表將包含對相同對象的引用。這很好,如果它們是不可變的(比如字符串),但如果你想創建更深的副本,則需要做更多的工作。

順便說一句,您有沒有任何理由不使用泛型?例如,我可能會使用:

LinkedList<ArrayList<String>> partials = new LinkedList<ArrayList<String>>(); 
ArrayList<String> list = new ArrayList<String>(); 
list.add("Test"); 

// Create a shallow copy and add a reference to that into the linked list 
partials.add(new ArrayList<String>(list)); 

list.add("Another element"); 

// Prints 1, because the lists are distinct 
System.out.println(partials.element().size()); 

如果沒有什麼應該改變鏈表列表中的內容,你可能想看看在Guava提供的一成不變的集合,或使用Collections.unmodifiableList包裝你的克隆。請注意,後者僅在原始列表上創建了視圖,因此您仍然需要先執行克隆步驟。

+1

...或使用Collections.unmodifiableList – MeBigFatGuy 2011-03-30 06:38:00

+0

在實際的代碼中,我使用的是泛型,但是爲了讓這個例子更簡單些,我省略了它們。 – Charlotte 2011-03-30 06:38:54

+0

@Charlotte:一般來說,讓您的示例代碼代表您的真實代碼是個不錯的主意。 – 2011-03-30 06:40:02

1

實際上,代碼無法在第3行進行編譯:partials.element()返回一個Object(LinkedList的第一個元素),如果要以這種方式使用它,則必須將其轉換爲ArrayList。

我同意你不需要泛型使代碼更易於添加。您也可以將partials和head定義爲List而不是LinkedList & ArrayList。使用接口而不是實現是一種很好的做法,並且可以避免在不需要的時候使用過多的特定方法,如element()。