2011-11-22 38 views
16

可以將List<T>初始化爲包含給定數量的null s,其中T是列表所屬類別的類型參數?我肯定可以用循環做到這一點,但要知道是否有可能。初始化列表<T>給定數量的沒有循環的空值?

List<T> myList = new ArrayList<T>(numEls); 

創建給定容量的列表,但尺寸0,於是myList.get(x)失敗所有x,也是如此,例如myList.set(numEls-1,null)

myList = Arrays.asList(new T[numEls]); 

不編譯,並

myList = (List<T>) Arrays.asList(new Object[numEls]); 

編譯在Eclipse(與未檢查的投警告),而不是用javac。


更新:謝謝你的答案!然而,我發現另一個相當短的解決方案接近我上面的最後一次嘗試,它在eclipse和我們的自動編譯系統中編譯:投射數組,而不是列表!那麼

List<String> list = new ArrayList<String>(Arrays.asList(new String[100])); 
for(String string : list){ 
    System.out.println(string); 
} 

,你可以寫一個層次:

myList = Arrays.asList((T[]) new Object[numEls]); 
+1

爲什麼你需要解決這個沒有循環?這是非常不合理的。只需調用'ensureCapacity',然後* n *次'add(null)'即可。 –

+0

@RolandIllig我沒有_need_解決它沒有循環,我只想知道它是否可能。 –

+0

爲什麼要用這麼長的時間來避免單線循環,用更復雜的東西代替呢?如果你知道你想包裝一個Object []的大小。 –

回答

1

如果你想要一個ArrayList你可以使用反射來欺騙

ArrayList<T> myList = new ArrayList<T>(numEls); 
Field f = ArrayList.class.getField("size");//cache this 
f.setAccessible(true); 
f.setInt(myList, numEls); 
+0

沒有Class對象參數或不必要的數組副本的解決方案!謝謝。 Nitpick:'getField(String)'僅用於公共字段,'getDeclaredField'是必需的。 –

+0

這似乎很危險;因爲它根本不會更新(推測)後備陣列,所以看起來後面可能會拋出AIOOBE - 例如,當內部容量仍然充足時,「添加」後會發生什麼?它不是**我想要處理的一個錯誤。 – 2012-09-27 23:27:08

+0

@pst note我使用了容量構造函數,所以它會匹配,但的確是一個利基應用 –

0

試試這個

class Base<T>{ 
    protected List<T> list; 

    public List<T> getList(){ 
     return list; 
    } 
} 

class Child extends Base<String>{ 
    public Child(){ 
     list = new ArrayList<String>(Arrays.asList(new String[100])); 
    } 
} 

它可以在接下來的方式使用:

Base<String> base = new Child(); 
base.getList(); 
+2

但我不想要一個'List ',我想要一個'List ',其中什麼都不知道'T'(至少與列表創建沒有關係)。 –

+0

這篇文章沒有回答這個問題。顯然它可以用具體類型,但@ arme.b想要爲* generic *類型編寫代碼。 – AlexR

+0

請查看更新後的示例。 – StKiller

5

你需要使用反射使用Array.newInstance()實例化一個支持數組T[]

public static <T> List<T> getListWithNulls(Class<T> componentType, int length) { 
    T[] array = (T[])Array.newInstance(componentType, length); 
    return new ArrayList<T>(Arrays.asList(array)); 
} 

正如你所看到的,這需要較T類型的Class<T>對象的引用:

List<String> strListWithNulls = getListWithNulls(String.class, 100); 

還要確保不要混淆類java.lang.reflect.Arrayjava.util.Arrays這兩個都在這裏使用。

最後,請注意反射將比僅使用循環慢得多。

+1

爲什麼你需要新的ArrayList ? Arrays.asList已經返回一個List實例。 – dmeister

+2

@dmeister - [該方法](http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T ...))返回一個由List支持的List陣列。爲了有一個可調整大小的列表,它需要被複制到另一個'List'實現。 –

+0

@KublaiKhan謝謝!事實上,dmeister的建議將符合目的,因爲列表大小在我的情況下是固定的(但我沒有在問題中說過)。無論如何,我希望有一個解決方案的代碼比循環短,但如果我不能這樣做,我不會責怪這個使者。 ;-) –

2

不是一個真正的解決方案,但你想避免循環。

void fillNullList(List<T> list, count) { 
    if (count > 0) { 
     list.add(null); 
     fillNullList(list, count - 1); 
    } 
} 

說真的,你爲什麼要避免循環?可能地,您需要一個具有O(1)複雜性而不是O(n)複雜性解決方案的解決方案,而不管是否使用循環。

2

我只是使用一個循環,它更簡單,可能也更快。

List<T> list = 
while(list.size()<size) list.add(null); 

您使用的任何其他方法可能會爲您使用循環。如果這沒問題,只需編寫你自己的隱藏所用循環的方法。

4

你可能需要的是這樣的....

final int maxSize = 50; 

List<T> v = new Vector<T>() {{setSize(maxSize);}}; 

向量允許您設置大小,這與null的填充它們。

+0

不錯的一個!我會使用Vector來初始化一個ArrayList,類似於'List v = new ArrayList (new Vector (){{setSize(maxSize);}});'但很好的想法。 – OldCurmudgeon

+0

確實很有趣!就我所見,用一個額外的變量而不是雙括號初始化,這裏沒有隱藏的循環:'Vector tmp = new Vector (maxSize);'創建一個期望大小的內部數組'tmp。 setSize(maxSize);'確保vector的'toArray()'返回一個這樣大小的數組,這個數組被@ Paul的建議中的'ArrayList'構造函數使用! (然而,該陣列被不必要地複製了一次。) –

+0

事實上,開發人員經常會忽視Vector,因爲它只是ArrayList的同步版本,並且出於同樣的原因被駁回,但它確實可以啓用這樣的小寶石。 – Crollster

3

如果你不需要變異列表...

List<T> result = Collections.nCopies(num, (T) null); 

...或交替

List<T> result = new ArrayList<T>(Collections.nCopies(num, (T) null)); 
+0

請解釋第二個選項。當我嘗試訪問列表時使用它,它給了我NullPointerException。我的代碼列表 psDTOs = new ArrayList (Collections.nCopies(15,(ProfileSectionDTO)null)); –

+0

你如何訪問列表?它充滿了空值。 –

+0

是的。愚蠢的我。謝謝。 –

0

我做的是

MyClass[] array = {new MyClass(), new MyClass(), new MyClass(), new MyClass(), new ProfileSectionDTO(), new MyClass()}; 
List<MyClass> MyClassList = Arrays.asList(array); 

髒,但工作:)

相關問題