在Java中,允许将一个数组变量拷贝给另一个数组变量。这时,两个变量将引用同一个数组:
int [] luckyNumbers = smallPrimes;
luckyNumbers [5] = 12;//此时 smallPrimes[5] 也是 12
如果要将一个数组的所有值拷贝到一个新的数组中去,就要使用 Arrays 类的 copyOf 方法:
int [] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckNumbers.length);
第二个参数是新数组的长度。这个方法通常用来增加数组的大小:
luckNumbers = Arrays.copyOf(luckyNumbers, 2 * luckyNumbers.length);
如果数组元素是数值型,那么多余的元素将被赋值为 0 ;如果数组元素是布尔型,则将赋值为 false 。相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。
数组的拷贝除了以上提到的方法外还有三种拷贝方法(1. for 循环拷贝 2. clone 3. System.arraycopy ),下面将对这四种方法进行举例说明。(浅拷贝:数组拷贝后修改数组中的值,原数组也发生变化)
1. for 循环
使用循环语句,将源数组的每个元素复制到新数组对应的元素。
- 优点:灵活
- 缺点:需要编码
拷贝语句代码:
for (int i = 0; i < testArrays.length; i++) {//浅拷贝
testArrays2[i] = testArrays[i];
}
例:
class TestArray {
private int val = 10;//只能在TestArray中用
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
}
public class TestDemo1 {
public static void main(String[] args) {
TestArray[] testArrays = new TestArray[3];
testArrays[0] = new TestArray();
testArrays[1] = new TestArray();
testArrays[2] = new TestArray();
TestArray[] testArrays2 = new TestArray[3];
/********************** for 循环拷贝********************/
for (int i = 0; i < testArrays.length; i++) {//浅拷贝
testArrays2[i] = testArrays[i];
}
/******************************************************/
System.out.println("========拷贝后==========");
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal() + "\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal() + "\t");
}
System.out.println();
System.out.println("=========修改后==========");
testArrays2[0].setVal(10000);
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal() + "\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal() + "\t");
}
System.out.println();
}
}
2.Object.clone()
使用数组变量的 clone() 方法
- 优点:简单
- 缺点:不够灵活
源码:
拷贝语句代码:
TestArray[] testArrays2 = testArrays.clone();
例:
class TestArray {
private int val = 10;//只能在TestArray中用
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
}
public class TestDemoClone {//浅拷贝
public static void main(String[] args) {
TestArray[] testArrays = new TestArray[3];
testArrays[0] = new TestArray();
testArrays[1] = new TestArray();
testArrays[2] = new TestArray();
/***********************clone拷贝**************************/
TestArray[] testArrays2 = testArrays.clone();
//不需要给 testArrays2 定义长度,直接将原数组完全拷贝。
/*********************************************************/
System.out.println("========拷贝后==========");
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal() + "\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal() + "\t");
}
System.out.println();
System.out.println("=========修改后==========");
testArrays2[0].setVal(10000);
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal() + "\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal() + "\t");
}
System.out.println();
}
}
3.System.arraycopy()
System.arraycopy(src, srcPos, dest, destPos, length)是 System 类提供的一个静态方法,可以用来实现数组之间的复制。
(1)src:源数组。
(2)srcPos:源数组要复制的起始位置。
(3)dest:目的数组。
(4)destPos:目的数组放置的起始位置。
(5)length:复制的长度。
源码:
native :底层代码有C/C++实现
Objece src:源数组(要拷贝的)
srcPos:源数组的起始位置 并不是一定就是0号位置
Object dest:新数组
destPos:目的地数组的起始位置
length:拷贝源数组的多长
拷贝语句代码:
System.arraycopy(testArrays,0,testArrays2,0,testArrays.length);
例:
class TestArray {
private int val = 10;//只能在TestArray中用
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
}
public class TestDemoSystem {//浅拷贝
public static void main(String[] args) {
TestArray[] testArrays =new TestArray[3];
testArrays[0] = new TestArray();
testArrays[1] = new TestArray();
testArrays[2] = new TestArray();
TestArray[] testArrays2 =new TestArray[testArrays.length];
/************************System.arraycopy拷贝************************/
System.arraycopy(testArrays,0,testArrays2,0,testArrays.length);
//testArrays:想要拷贝的数组。
//0 :从哪个位置开始拷贝
//testArrays.length:要拷贝的长度
/*******************************************************************/
System.out.println("========拷贝后==========");
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal()+"\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal()+"\t");
}
System.out.println();
System.out.println("=========修改后==========");
testArrays2[0].setVal(10000);
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal()+"\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal()+"\t");
}
System.out.println();
}
}
4.Arrays.copyOf()
Arrays.copyOf()拷贝底层调用System.arraycopy()
- 简单灵活
- 推荐使用
源码:
original:原始的数组
newLength:新的长度
拷贝语句代码:
TestArray[] testArrays2 = Arrays.copyOf(testArrays,testArrays.length);
例:
class TestArray {
private int val = 10;//只能在TestArray中用
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
}
public class TestDemoArraysCopyOf {//浅拷贝
public static void main(String[] args) {
TestArray[] testArrays =new TestArray[3];
testArrays[0] = new TestArray();
testArrays[1] = new TestArray();
testArrays[2] = new TestArray();
/***********************Arrays.copyOf()拷贝**************************/
TestArray[] testArrays2 = Arrays.copyOf(testArrays,testArrays.length);
//testArrays:要拷贝的数组
//testArrays.length:要拷贝的长度
/*******************************************************************/
System.out.println("========拷贝后==========");
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal()+"\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal()+"\t");
}
System.out.println();
System.out.println("=========修改后==========");
testArrays2[0].setVal(10000);
System.out.println("========================");
for (int i = 0; i < testArrays.length; i++) {
System.out.print(testArrays[i].getVal()+"\t");
}
System.out.println();
for (int i = 0; i < testArrays2.length; i++) {
System.out.print(testArrays2[i].getVal()+"\t");
}
System.out.println();
}
}
以上四种拷贝方式运算结果均如下:
总结:
1> clone() 和 Arrays.copyOf() 会产生新的对象
2> 循环拷贝:浅拷贝,速度相对较慢
3> System.arraycopy 拷贝:浅拷贝,源码中有关键字 native ,说明它不是用 Java 语言写的,而是调用其他语言(C/C++)的代码。
4> Arrays.copyOf 拷贝:浅拷贝,调用 System.arraycopy
5> Object.clone 拷贝:①对象拷贝:深拷贝 ②数组拷贝:浅拷贝 ,源码中有关键字 native ,所以也是底层由C语言实现。