简述
编程的过程中,经常会遇到的一个问题是需要将一个数组当中的元素复制到另一个数字来操作或者保存。这时,一种简单高效的方法就显得尤为重要。
首先要申明的是,数组属于引用类型。如果使用了 array1 = array2 这样的方法,试图去复制数组是不可能的,该语句并没有将array1引用指向的数组的内容复制给array2,而是将array1的引用值复制给了array2.也就是说,array1 和 array2指向了同一个数组,数组的地址发生了复制,而数组的内容并没有复制。这样操作的结果是array2访问到的数组是array1原本指向的数组,但是如果利用array2对数组进行操作,array1同样会发生变化。这种效果显然不是复制想要的结果。
如果想要真正的复制数组,有三种方法可以使用:
- 使用循环语句逐个地复制数组的元素
- 使用System类中的静态方法arraycopy
Arrays类的copyOf方法(处理arraycopy方法无法处理的长度不足问题)- 使用clone方法复制数组
1.for循环完全复制
public class Demo{
public static void main(String[] args){
int[] arr = {1, 2, 3, 4, 5};
int[] arr1 = new int[5];
//将arr所有元素的值复制到arr1当中
for(int index = 0; index < arr.length; i++){
arr1[i] = arr[i];
}
}
}
就这样,我们在遍历的同时,就实现了元素的复制。
但是,这样的方法存在一定的局限性:
如果我并不希望完全复制,仅仅是将 arr 中的一部分元素复制到 arr1 中的一段位置呢?
这时,就需要另外设置一些变量,并且计算这些变量和两个数组之间的关系等,过程就变的相当复杂了。
但是好在Java已经给我们提供了数组复制的方法,可以直接拿来用。
2.System.arraycopy(Object src, int srcPos,Object dest, int destPos, int length)
参数的意义:
- src:原数组
- srcPos:原数组的起始下标
- dest:目标数组
- destPos:目标数组的起始下标
- length:复制的长度
使用示例:
public class ArrayCopyDemo {
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
int[] a = new int[4];
System.arraycopy(arr, 2, a, 1, 2);
for(int i = 0; i < a.length; i++) {
System.out.print(a[i] + "\t");//0, 30, 40, 0
}
System.out.println();
// System.arraycopy(arr, 2, a, 1, 5);//下标越界
// System.arraycopy(arr, 2, a, 3, 2);//下标越界
}
}
以上代码表示将arr数组的第三四个元素复制到数组a的第二三个位置。
使用注意事项:
- 起始下标的值和复制长度相加之后,不可以超出数组的长度大小。
- arraycopy就是系统定义好的方法名,不要根据Java的命名习惯自行更改为arrayCopy.
int[] arr1 = Arrays.copyOf(arr, length);
功能:
实现数组的复制,返回复制后的数组。参数是被复制的数组和复制的长度,如果新数组的长度超过原数组的长度,则保留数组默认值,如果新数组的长度小于原数组的长度,会舍弃超出的那一部分。
示例代码:
import java.util.Arrays;
public class CopyOfDemo {
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
int[] a = new int[4];
a = Arrays.copyOf(arr, 1);
for(int index = 0; index < a.length; index++) {
System.out.print(a[index] + "\t");
}
System.out.println();
a = Arrays.copyOf(arr, 5);
for(int index = 0; index < a.length; index++) {
System.out.print(a[index] + "\t");
}
System.out.println();
a = Arrays.copyOf(arr, 8);
for(int index = 0; index < a.length; index++) {
System.out.print(a[index] + "\t");
}
System.out.println();
}
}
运行结果如下图所示:
方法比较
arraycopy这种方法运用相当灵活,能够实现数组复制过程中所有想要实现的组合,随便从什么位置开始复制,随便复制到什么位置。
但是arraycopy有一种限制,就是不能突破数组长度的限制,这个时候,就有了copyOf这个方法来解决这个问题——扩容。
如果觉得很难理解,不妨看一下copyOf的源代码
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
难道copyOf仅仅适用于int类型的数组?当然不是啦,这个方法时重载的,有其他类型的,我只截了这一个。
正是由于它用 newLength 重新定义了数组之后又返回,所以给我们一种数组扩容的假象。同时,由于它方法内部调用了arraycopy方法,所以在不需要扩容的时候还是直接使用arraycopy方法好一些。
3. clone方法
clone()方法是定义在Object类中的一个方法,用于创建一个新的完全一样的对象。
但是,clone()方法返回的是一个Object对象,所以复制数组的时候需要类型强转,使用示例如下:
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int[] array = (int[])(arr.clone());
随后,访问array数组,可以发现与arr是一致的,而且,操作array之后,arr没有改变,是完整意义的数组复制。
以上就是数组复制的一些基本方法,可以根据实际的需求自行选择。