一、数组浅拷贝的4种方式
1. 使用 copyOf() 方法对数组进行复制
jdk1.8的API文档中关于Arrays的copyOf方法:
-
-
static boolean[]
copyOf(boolean[] original, int newLength)
使用 false (如有必要)复制指定的数组,截断或填充,以使副本具有指定的长度。
static byte[]
copyOf(byte[] original, int newLength)
复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
static char[]
copyOf(char[] original, int newLength)
复制指定的数组,截断或填充空字符(如有必要),以便复制具有指定的长度。
static double[]
copyOf(double[] original, int newLength)
复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
static float[]
copyOf(float[] original, int newLength)
复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
static int[]
copyOf(int[] original, int newLength)
复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
static long[]
copyOf(long[] original, int newLength)
复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
static short[]
copyOf(short[] original, int newLength)
复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
static <T> T[]
copyOf(T[] original, int newLength)
复制指定的数组,用空值截断或填充(如有必要),以便复制具有指定的长度。
static <T,U> T[]
copyOf(U[] original, int newLength, 类<? extends T[]> newType)
复制指定的数组,用空值截断或填充(如有必要),以便复制具有指定的长度。
-
2. 使用 CopyOfRange() 方法对数组进行复制
jdk1.8的API文档中关于Arrays的CopyOfRange方法:
-
-
static boolean[]
copyOfRange(boolean[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static byte[]
copyOfRange(byte[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static char[]
copyOfRange(char[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static double[]
copyOfRange(double[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static float[]
copyOfRange(float[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static int[]
copyOfRange(int[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static long[]
copyOfRange(long[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static short[]
copyOfRange(short[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static <T> T[]
copyOfRange(T[] original, int from, int to)
将指定数组的指定范围复制到新数组中。
static <T,U> T[]
copyOfRange(U[] original, int from, int to, 类<? extends T[]> newType)
将指定数组的指定范围复制到新数组中。
-
3.使用 arraycopy() 方法
jdk1.8的API文档中关于System的arraycopy方法:
-
-
-
参数
src
- 源数组。srcPos
- 源数组中的起始位置。dest
- 目标数组。destPos
- 目的地数据中的起始位置。length
- 要复制的数组元素的数量。
-
-
4.使用 clone() 方法
clone() 方法也可以实现复制数组。该方法是类 Object 中的方法,可以创建一个有单独内存空间的对象。因为数组也是一个 Object 类,因此也可以使用数组对象的 clone() 方法来复制数组。
clone() 方法的返回值是 Object 类型,要使用强制类型转换为适当的类型。
对于基本数据类型的数组:
一维数组:深克隆;(重新分配空间,并将元素复制过去)
二维数组:浅克隆。(只传递引用)
二、数组深复制的方式
如何实现二维数组的深克隆呢?
对每一维数组调用clone方法。
int[][] a={{3,1,4,2,5},{4,2}};
int[][] b=new int[a.length][];
for(int i=0;i<a.length;i++){
b[i]=a[i].clone();
}
b[0][0]=10;
System.out.println(b[0][0]+" "+a[0][0]);
System.out.println(b[0]==a[0]);
一维对象数组的克隆
//浅克隆
class MyClass {
int a;
MyClass(int a){
this.a = a;
}
@Override
public String toString() {
return ""+a;
}
void changeValue(int x){
a = x;
}
}
public class Blah
{
public static void main(String[] args) {
MyClass[] a={new MyClass(1),new MyClass(2), new MyClass(3),new MyClass(4),new MyClass(5)};
MyClass[] b=a.clone();
b[0].changeValue(10);
System.out.println(b[0]+" "+a[0]);//输出10 10
}
}
//深克隆
class MyClass implements Cloneable{
private int a;
MyClass(int a){
this.a = a;
}
@Override
public String toString() {
return ""+a;
}
void changeValue(int x){
a = x;
}
@Override
public MyClass clone(){
MyClass myClass = null;
try {
myClass = (MyClass) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
/*如果类中存在非基本类型的属性,需要在这里对属性进行克隆(通过调用属性的clone()方法。*/
return myClass;
}
}
public class Blah {
public static void main(String[] args) {
MyClass[] a={new MyClass(1),new MyClass(2), new MyClass(3),new MyClass(4),new MyClass(5)};
MyClass[] b = new MyClass[a.length];
for(int i = 0; i < a.length; i++){
b[i] = a[i].clone();
}
b[0].changeValue(10);
System.out.println(b[0]+" "+a[0]);//输出10 1
}
}