在java语言中 ,Java数组的复制操作可以分为深度复制和浅度复制。
简单来说深度复制,可以将对象的值和对象的内容复制;
浅复制是指对对象引用的复制。
第一种方法:clone() 方法
clone() 方法可以实现复制数组。该方法是类 Object 中的方法,可以创建一个有单独内存空间的对象。因为数组也是一个 Object 类,因此也可以使用数组对象的 clone() 方法来复制数组。
clone() 方法的返回值是 Object 类型,要使用强制类型转换为适当的类型。其语法形式比较简单:
array2 = array1.clone()
下面是一个测试实例:
import java.util.Scanner;
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] array1 = new int[]{1,3,5,7,9};
int[] array2 = new int[array1.length];
//开一个与array1长度相同的数组array2
array2 = array1.clone();
System.out.println("array1 = "+Arrays.toString(array1));
System.out.println("array2 = "+Arrays.toString(array2));
System.out.println("===========================");
array2[0] = 100;
System.out.println("array1 = "+Arrays.toString(array1));
System.out.println("array2 = "+Arrays.toString(array2));
System.out.println("array1 的地址是: " + array1);
System.out.println("array2 的地址是: " + array2);
array2 = array1.clone();
System.out.println("array2 的地址是: " + array2);
}
}
输出如下:
到这里大家发现了什么???显然在上述图中出现了三种地址。
这三种地址的关系如下图所示:
可以看到,刚开始通过 int[] array2 = new int[array1.length] 语句申请的数组和array2 = array1.clone() 语句产生的数组并不是同一个数组。
小编上网查看clone()方法的源码,找到:总纲是Creates and returns a copy of this object. 意思是“ 创建并返回此对象的副本。”就可以理解为什么array2数组克隆前后指向不同的地址了!!!
对于clone()方法站在更高角度是这样解释的:
当对复制数组的某个元素进行改变时,被复制数组对应元素也随之改变,即对于引用数据类型来说clone()方法是浅拷贝。
通过内存分析可以很直观的看到,每个数组的元素分别指向同一个内存地址,当通过其中一个数组的某个元素对被指向地址的数值进行更改时,另一个数组相应的元素同样会发生改变。
第二种方法:System.arraycopy 方法(本地方法)
public static native void arraycopy(Object src, int srcPos, Object dest, int desPos, int length)
这句话是什么意思呢:(一共有五点)如下:
(原数组, 原数组的开始位置, 目标数组, 目标数组的开始位置, 拷贝个数)
import java.util.Scanner;
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = new int[10];
System.arraycopy(a1, 1, a2, 3, 3);
System.out.println(Arrays.toString(a1)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)); // [0, 0, 0, 2, 3, 4, 0, 0, 0, 0]
}
}
看看上面的测试code,a1为原数组,a2为目标数组,System.arraycopy()这个方法,对a1的本身没有影响,emmmmmm
(原数组, 原数组的开始位置, 目标数组, 目标数组的开始位置, 拷贝个数)
(就上述code)从a1数组的第2个元素——“2”,开始对之后的元素,进行复制。(obj数组类似)
拷贝个数,控制从a1数组复制黏贴到a2数组上元素的个数。
第三中方法:Arrays.copyOf
同样看源码,它的实现还是基于System.arraycopy(),所以效率自然低于System.arraycpoy()
Arrays的copyOf()方法传回的数组是新的数组对象,改变传回数组中的元素值,不会影响原来的数组。copyOf()的第二个自变量指定要建立的新数组长度,如果新数组的长度超过原数组的长度,则保留数组默认值,如下:
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] a1 = {1, 2, 3, 4, 5}; //初始化
int[] a2 = Arrays.copyOf(a1, 5);
int[] a3 = Arrays.copyOf(a1, 10);
for(int i = 0; i < a2.length; i++)
System.out.print(a2[i] + " ");
System.out.println();
for(int i = 0; i < a3.length; i++)
System.out.print(a3[i] + " ");
}
}
/**1 2 3 4 5
1 2 3 4 5 0 0 0 0 0 */
第四种方法:Arrays.copyOfRange
Arrays.copyOfRange底层其实也是用的System.arraycopy,只不过封装了一个方法
要使用这个方法,首先要import java.util.*;
Arrays.copyOfRange(T[ ] original,int from,int to)
将一个原始的数组original,从小标from开始复制,复制到小标to,生成一个新的数组。
注意这里包括下标from,不包括上标to。
这个方法在一些处理数组的编程题里很好用,效率和clone基本一致,比利用循环复制数组效率要高得多。
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] a= {1,2,3,4,5,6,7,8,9,10};
int[] b=new int[8];
b=Arrays.copyOfRange(a, 2, 10);
System.out.print(Arrays.toString(b));
}
}
//[3, 4, 5, 6, 7, 8, 9, 10]
显然,方法中的copyOfRange(a,2,10),分别指数组a,a的第3个元素,a的第10个元素。
希望对大家有所帮助,谢谢!!!