实际开发中经常会用到将集合转换成数组进行操作,Collection有两种方法可以进行数组的转换。
首先看下Collecction的这两个方法的说明:
Object[ ] toArray() :返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)。
<T> T[ ] toArray(T[] a):返回按适当顺序(从第一个元素到最后一个元素)包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
Collection<String> arr = new ArrayList<String>();
arr.add("a");
arr.add("b");
arr.add("b");//可以添加重复的对象
Object[] obj = arr.toArray();//第一种方法
// String[] str = (String[])arr.toArray();//error
String[] obj1 = arr.toArray(new String[3]);//第二种方法
针对上面注释的那行代码报错进行分析:
这里的问题其实是一个数组的类型,及类型转换的问题。这里解释这个问题需要先来看一个数组的声明的分析:
Object[] objArray = new String[3];
该语句的意义是,一个String[]类型的数组向上造型赋值给一个Object[]类型的引用;这一步是可以成功的,因为String[]类型是Object[]的子类。所以很自然的可以想到此时可以将objArray向下造型为String[]。
arr.toArray[]这句代码生成的是一个Object[]类型的数组。所以其不可以向下造型成String[]的类型。而arr.toArray(new String[3])这句代码返回的就是一个String[]类型的数组。如下是Vector的源码实现:
/**
* Returns an array containing all of the elements in this Vector
* in the correct order.
*
* @since 1.2
*/
public synchronized Object[] toArray() {
return Arrays.copyOf(elementData, elementCount);
}
/**
* Returns an array containing all of the elements in this Vector in the
* correct order; the runtime type of the returned array is that of the
* specified array. If the Vector fits in the specified array, it is
* returned therein. Otherwise, a new array is allocated with the runtime
* type of the specified array and the size of this Vector.
*
* <p>If the Vector fits in the specified array with room to spare
* (i.e., the array has more elements than the Vector),
* the element in the array immediately following the end of the
* Vector is set to null. (This is useful in determining the length
* of the Vector <em>only</em> if the caller knows that the Vector
* does not contain any null elements.)
*
* @param a the array into which the elements of the Vector are to
* be stored, if it is big enough; otherwise, a new array of the
* same runtime type is allocated for this purpose.
* @return an array containing the elements of the Vector
* @throws ArrayStoreException if the runtime type of a is not a supertype
* of the runtime type of every element in this Vector
* @throws NullPointerException if the given array is null
* @since 1.2
*/
@SuppressWarnings("unchecked")
public synchronized <T> T[] toArray(T[] a) {
if (a.length < elementCount)
return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
System.arraycopy(elementData, 0, a, 0, elementCount);
if (a.length > elementCount)
a[elementCount] = null;
return a;
}