2011-02-27 38 views
1

我正在嘗試編寫一個方法,它接受List並根據它創建一個新的List。也就是說,如果輸入列表是ArrayList,那麼我想要該方法創建一個新的ArrayList。問題在於程序直到運行時纔會知道該列表是否爲ArrayListLinkedList如何在Java中創建與舊列表相同類型的新列表?

到目前爲止,我已經嘗試過使用clone()方法,但我不認爲它可行,因爲List類沒有定義clone(),並且當我將輸入列表作爲Object並且然後克隆然後重新改寫爲一個列表,它也不起作用(我不知道爲什麼)。

+1

你能說一點關於爲什麼你需要做到這一點,而不是簡單地說總是返回已知長度的輸入列表方便的名單? – andersoj 2011-02-27 04:17:12

+0

另一方面,Scala集合庫通過有效地添加一個額外參數來完成此操作,該參數是您想要返回的列表類型的構建器。編譯器完成所有繁重的工作(通過「implicits」),並隱藏了庫的用戶的大部分細節。 – joev 2011-02-27 16:11:20

回答

1

你能多談談你爲什麼要這麼做?如果沒有一個很好的理由,我想抗衡:

考慮不這樣做的所有,而是:

static <T> List<T> cloneMyList(final List<T> source) 
{ 
    return new ArrayList<T>(source); 
} 

如果你真正想要的是創建一個已知列表的第二個副本的有效方式,也許底層的實現類型並不重要。在這種情況下,只需使用ArrayList即可使用List拷貝構造函數進行高效分配。

+0

所以這樣做的目的是有一個方法,可以找到兩個列表的聯合並將其作爲與輸入列表相同類型的另一個列表返回。那就是如果我加入LinkedList,我想要一個LinkedList出來。所以我並不需要已知列表的第二個副本,我需要的是初始化相同類型的列表。 – crumbs357 2011-02-27 04:59:12

+0

@crumbs:但是爲什麼你關心返回類型是相同的實現類型?如果不是,會破壞什麼?如果兩個輸入列表是不同類型的(例如)呢? – andersoj 2011-02-27 04:59:54

+0

這是一個類的任務的一部分,所以它真的很隨意。沒有理由爲什麼我必須讓返回類型與實現類型相同,但似乎是正確的。另外,我已經考慮了不同的輸入類型問題,並決定將返回類型從第一個參數中取出。 – crumbs357 2011-02-27 05:06:02

2

所有從JDK支持克隆的標準列表,所以

List copy = (List)((Cloneable)somelist).clone() 

應該正常工作。

當然,你可以使用反射

Class c = somelist.getClass(); 
List newlist = (List)c.newInstance(); 
newlist.addAll(somelist); 
+0

反射示例不需要鑄造。 newInstance()應該返回一個列表的子元素 – tanyehzheng 2011-02-27 04:00:44

+0

@tanyehzheng - 在寫例子中,類型cast **是**必需的。是的,newInstance()將返回預期類的實例,但在編寫的代碼中,編譯器只知道它是Object或某個子類型。現在,如果'c'被聲明爲'Class <?擴展List>'類型轉換不是必需的。 – 2011-02-27 04:17:28

+2

@MeBigFatGuy - 除非您首先將'List'轉換爲其實際的類,否則'clone()'方法將失敗。 'clone()'方法不在'List'的公共API中......只能在實現'List'的標準集合類中使用。 – 2011-02-27 04:26:13

-1

這就是:

List<YourType> destinationList = new ArrayList<>(sourceList.size()); 
Collections.copy(destinationList, sourceList); 
相關問題