转贴来自:http://www.ibm.com/developerworks/cn/java/j-arrays/#3
使用数组可以做很多事。如果数组的初始大小已无法满足您的需要,您就需要创建一个新的更大的数组,然后将原始元素复制到更大数组的相同位置。但是,如果您不需要将数组变大,而只希望在使原始数组保持原样的基础上修改数组元素,您必须创建数组的一个副本或克隆版本。
System
类中的 arraycopy()
方法允许您将元素从一个数组复制到另一个数组。当进行这种复制时,目标数组可以大些;但如果目标数组比源数组小,就会在运行时抛出一个 ArrayIndexOutOfBoundsException
异常。 arraycopy()
方法用到 5 个参数(两个用于数组,两个用作数组的起始位置,还有一个表示复制元素的数量): public static void arraycopy (Object sourceArray,int sourceOffset,Object destinationArray,int destinationOffset,int numberOfElementsToCopy)
。 除了类型的兼容性,这里唯一的必要条件是已经为目标数组分配了内存。
警告:当在不同的数组之间复制元素时,如果源参数或目标参数不是数组,或者它们的类型不兼容,就会抛出 ArrayStoreException 异常。不兼容的数组比如一个是基本数据类型数组而另一个是对象数组;或基本数据类型不同;或对象类型不可赋值。
为了演示,清单 2-2 采用一个整型数组并创建一个两倍大的新数组。下面示例中的 doubleArray()
方法为我们做到了这一点:
public class DoubleArray { public static void main (String args ]) { int array1[] = {1, 2, 3, 4, 5}; int array2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; System.out.println("Original size: " + array1.length); System.out.println("New size: " + doubleArray(array1).length); System.out.println("Original size: " + array2.length); System.out.println("New size: " + doubleArray(array2).length); } static int[] doubleArray(int original[]) { int length = original.length; int newArray[] = new int[length*2]; System.arraycopy(original, 0, newArray, 0, length); return newArray; } } |
在获得源数组的长度以后,先创建适当大小的新数组,再把原始元素复制到新数组中相同的位置。在您了解数组的反射以后,您可以总结出将任意类型数组的大小加倍的方法。
执行程序,生成如下输出:
Original size: 5 New size: 10 Original size: 9 New size: 18 |
注意:当用 arraycopy()
进行复制时,如果您要将数组的子集复制到该数组内的另一个区域,源数组和目标数组可以是同一个。即使有些地方发生重叠也会生效。
因为数组实现了 Cloneable
接口,除了复制数组的区域以外,还可以克隆它们。 克隆包括创建一个同样大小和类型的数组,并将所有的原始元素复制到新数组里。这和复制不同,复制要求您自己创建目标数组并限定其大小。对基本数据类型的元素来说,新数组包含原始元素的副本,所以一个数组中元素的变化不会反映到它的副本中。但对于对象引用的情况,复制的只是引用。因而,数组的两个副本将指向同一个对象。对该对象的更改将反映到两个数组中。这叫做 浅拷贝或者 浅克隆。
为了演示,下面的方法采用了一个整型数组并返回上述数组的一个副本。
static int[] cloneArray(int original[]) { return (int[])original.clone(); } |
数组克隆用一个实际起作用的 public 方法覆盖了被保护起来的 Object
方法,后者通常会抛出 CloneNotSupportedException
异常。