在某些情況下,我們希望能夠將 ArrayList 物件所存的內容轉換成陣列的形式,在 ArrayList 中提供了 toarray 方法來達到我們的需求。下面是 Java 所提供的 toarray 方法的原始碼:
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
public T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
有上面可知,我們有兩個方式可以使用 toarray 方法,一個是不帶任何參數 toarray 方法回傳 Object 陣列,另外一個是回傳你所傳入的型態陣列。
我們先來看 public
T[] toArray(T[] a) 的方法,從原始碼中,我們發現此方法會使用參數的 length 的屬性,代表該參數必須要先配置過記憶體才行,如果直接傳 null 給它會引發 "java.lang.NullPointerException" 的例外事件。再回頭看一下原始碼,會發現當你所配置的陣列元素小於目前 ArrayList 所儲存的元素時,toarray 方法會幫你配置足夠的元素來儲存目前 ArrayList 物件中所含的所有元素。而當你的所配置的陣列元素個數大於目前會將你所配置的第 size 元素設定為null。基本上你可以想成超出的元素都會被設置成 null 就可以。(PS: 要使用 ArrayList 其型態一定是參考型態,如果使用基本型態會出現編譯失敗 ,而物件陣列的預設值為 null)。
另外一個 toArray法是回傳 Object 陣列,由於兩個陣列基底型別不同時,不能互相參照,所以你無法直接將回傳的 Object 陣列轉成你要的型態陣列。但是你可以針對每個 Object 元素做轉型。
範例程式如下:
static void toArrayDemo() {
ArrayList<integer> list = new ArrayList<integer>(){{
add(1);
add(2);
add(3);
add(4);
}};
//"main" java.lang.NullPointerException
//Integer[] test = null;
//test = list.toArray(test);
// or Integer[] test = list.toArray(null);
// 配置的元素小於 ArrayList 所存的元素各數少時,
// toArray 會幫你重新配置足夠的陣列個數來儲存。
Integer[] test = list.toArray(new Integer[0]);
System.out.print("<1>[ ");
for (Integer val : test) {
System.out.print(val + " ");
}
System.out.println("]");
// 配置大於 ArrayList 所存的 元素個數,多餘的陣列元素都是 null
Integer[] test2 = list.toArray(new Integer[10]);
System.out.print("<2>[ ");
for (Integer val : test2) {
System.out.print(val + " ");
}
System.out.println("]");
// 配置符合目前 ArrayList 所含的元素個數
Integer[] test3 = list.toArray(new Integer[list.size()]);
System.out.print("<3>[ ");
for (Integer val : test3) {
System.out.print(val + " ");
}
System.out.println("]");
//無法將 Object 陣列轉成其他型態的陣列
//[Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
//Integer[] test4 = (Integer[] )list.toArray();
Object [] obj = list.toArray();
System.out.print("<4>[ ");
for (Object val : obj) {
// 你可以對每一個 Object 中的元素轉型成 Integer 型態的物件
// 因為我們宣告的 ArrayList 是儲存 Integer 物件,所以每一個
// Object 物件都是參考到 Integer 物件
System.out.print( ((Integer)val).intValue() + " ");
// 下面方式與上面轉型所列印出來的結果相同,因為每一個 Object 元素
// 都是參考到 Integer 物件,而 Integer 的 toString method 就是列印其值。
//System.out.print( val + " ");
}
System.out.println("]");
}
輸出結果:
<1>[ 1 2 3 4 ]
<2>[ 1 2 3 4 null null null null null null ]
<3>[ 1 2 3 4 ]
<4>[ 1 2 3 4 ]
補充:
Object[] obj = new Object[size] 與 Object[] intObj = new Integer[2] 的不同是,obj 陣列可以指定
任何型態的物件參考,每一個元素值不一定要儲存相同的物件。而 intObj 是參考到 Integer 陣列所以其元素只能儲存 Integer 物件,儲存其他型態物件會引發 "java.lang.ArrayStoreException" 例外事件。另外 intObj 是參考到 Integer 陣列,所以你可以將 intObj 指定給其他 Integer 陣列來參考。
範例程式如下:
static void arrayDemo() {
Object [] intobj = new Integer[2];
System.out.println("obj instance Integer[] = " + (intobj instanceof Integer[]));
obj[0] = new Integer(10);
//Exception in thread "main" java.lang.ArrayStoreException: java.lang.Float
//obj[1] = new Float(10.f);
Object [] obj2 = new Object[2];
System.out.println("obj2 instance Integer[] = " + (obj2 instanceof Integer[]));
obj2[0] = new Integer(10);
obj2[1] = new Float(10.f);
System.out.println("obj2[0] = " + obj2[0] + " , obj2[1] = " + obj2[1]);
}