2010-09-01 57 views
12

所以對於初學者讓說,我有一個LinkedList<String>Java的轉換通用的LinkedList到通用陣列

我可以很容易地通過toArray()將其轉換爲一個數組。即

LinkedList<String> strList = new LinkedList<String>(); 
String[] strArray = strList.toArray(new String[0]); 

但可以說我有一個LinkedList<T> 然後我下面的代碼:

LinkedList<T> tList = new LinkedList<T>(); 
T[] strArray = tList.toArray(new T[0]); 

我得到的無法創建牛逼錯誤信息的通用陣列。

我該如何解決這個問題?

特別是在我的班級中,我有LinkedList<AbstractNode<T>> nodes,並且我試圖實現getAll()方法,該方法將所有節點作爲數組返回。
謝謝!

注意PéterTörök的回答爲我的問題提供了正確的答案,但對於我只是簡單地返回一個ArrayList而不是[]作爲Bar提到的,最終使我的代碼更加平滑。
注2我的代碼看多一點我甚至不知道任何轉換是必要的,首先,LinkedList的是罰款,我試圖做...後: -/

回答

13

一種解決方法這是在該類庫中使用將是(使用未經檢查的鑄件)

public <T> T[] toArray(List<T> list, T[] a) { 
    if (a.length < list.size()) { 
    a = (T[])java.lang.reflect.Array.newInstance(
     a.getClass().getComponentType(), list.size())); 
    } 
    return list.toArray(a); 
} 

,或者與Class參數而不是數組:

public <T> T[] toArray(List<T> list, Class<T> k) { 
    return list.toArray(
      (T[])java.lang.reflect.Array.newInstance(k, list.size())); 
} 

從Java Generics and Collections,第6.4-5章。

無法創建通用數組是Java中最嚴重的限制之一。因爲它太討厭了,所以值得重申其發生的原因:泛型數組是有問題的,因爲泛型是通過擦除來實現的,但擦除是有益的,因爲它簡化了進化。

最好的解決方法是使用ArrayList或集合框架中的其他類優先於數組。我們在2.5節中討論了集合類和數組之間的權衡,並且我們注意到在很多情況下集合比數組更好:因爲它們在編譯時捕獲更多的錯誤,因爲它們提供更多的操作,並且因爲它們提供更多的表示的靈活性。到目前爲止,數組提供的問題的最佳解決方案是「只是說不」:使用集合優先於數組。

有時這不起作用,因爲您需要一個數組,因爲兼容性或效率的原因。這個例子發生在集合框架中:爲了兼容性,toArray方法將集合轉換爲數組[012]我們可能會嘗試的第一個解決方法是添加一個未經檢查的演員表,但我們很快會看到這導致更令人困惑的問題。正確的解決方案需要我們去反思。

+0

必須有一種不使用反射的方式,這個代碼塊中的「a」是什麼 a.getClass()。getComponentType() – 2010-09-01 12:30:40

+2

@krmby:不,沒有這種方式。泛型是通過使用Java中的擦除來實現的,這意味着編譯時類型是未知的,所以您只能通過獲取運行時類型來「作弊」,這意味着使用反射。你可能會傳入'Class '並在'newInstance()'中使用它,但這仍然是反射。 – 2010-09-01 12:34:29

+0

@krmby,遺憾的是沒有。請檢查更新的代碼。 – 2010-09-01 12:34:54

1

由於Java泛型是真的object型保換你的T和鑄造在編譯解決具體類型,有可能創造List<T>,但不T[]。 (第一個將是對象列表,第二個未知) 好的反射允許你做很多醜陋的黑客。你可以使用它們。我個人只有在沒有其他方式做某事時才使用它們。我不喜歡運行時錯誤。

但我的問題是:你真的需要T[],爲什麼不用ArrayList<T>來代替?

+0

有趣的是,我會給'ArrayList '旋轉 – 2010-09-01 12:49:01

+0

這很簡單 'return new ArrayList >(節點);'謝謝,這使我的代碼更清潔 – 2010-09-01 13:12:09

+0

我不得不改變選定的答案si彼得的回答在技術上是正確的,但感謝周圍的工作! – 2010-09-01 13:18:24