浅拷贝和深拷贝
java已有的拷贝方法中,都是对对象的引用进行了赋值,像c中的地址,对对象的实际值并没有赋值,即为浅拷贝。
深拷贝,对对象进行在内存中在进行复制一份进行存贮,对于java的对象,进行=号进行复制的时候都是复制引用的值,并不是实际地址,通过对象实现Cloneable接口,重写clone方法,复制时调用clone方法则实现的对象的深拷贝,数组则进行for循环进行对象的拷贝。
JAVA数组拷贝
1、通过for循环拷贝
浅拷贝,速度慢
//创建学生类
class student{
String name;
int age;
public student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public void copArray(){
student []original = new student[]{new student("张三",11),new student("李四",12),new student("王二",13)};//原数组
student []copyArray = new student[original.length];//拷贝数组
for (int i = 0; i < original.length; i++) {//for循环拷贝
copyArray[i] = original[i];
}
System.out.println("original[1] == copyArray[1]:"+ (original[1] == copyArray[1])); //输出true,元素内容并没有实际进行拷贝,浅拷贝
System.out.println("original == copyArray:"+ (original == copyArray)); //输出false,因为new了一个名指向原本数组内容,此数组名和原本数组名并不相同
original[0].name = "麻子";//修改原数组中元素,因为浅拷贝,所以会改变
for (student j : copyArray) {//输出拷贝的元素
System.out.print(j.toString()+" ");
}
System.out.println();
for (student j : original) {//输出原的元素
System.out.print(j.toString()+" ");
}
}
/*
输出结果
original[1] == copyArray[1]:true
original == copyArray:false
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
*/
2.clone拷贝数组
浅拷贝,速度慢,中等速度
//创建学生类
class student{
String name;
int age;
public student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public void copArray(){
student []original = new student[]{new student("张三",11),new student("李四",12),new student("王二",13)};//原数组
student []copyArray = new student[original.length];//拷贝数组
copyArray = original.clone();
System.out.println("original[1] == copyArray[1]:"+ (original[1] == copyArray[1])); //输出true,元素内容并没有实际进行拷贝,浅拷贝
System.out.println("original == copyArray:"+ (original == copyArray)); //输出false,因为new了一个名指向原本数组内容,此数组名和原本数组名并不相同
original[0].name = "麻子";//修改原数组中元素,因为浅拷贝,所以会改变
for (student j : copyArray) {//输出拷贝的元素
System.out.print(j.toString()+" ");
}
System.out.println();
for (student j : original) {//输出原的元素
System.out.print(j.toString()+" ");
}
}
/*
输出结果
original[1] == copyArray[1]:true
original == copyArray:false
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
*/
3.System.arraycopy进行拷贝
浅拷贝,速度较快,(native修饰,调用c/c++API进行实现的方法)
class student{
String name;
int age;
public student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public void cArray(){
student []original = new student[]{new student("张三",11),new student("李四",12),new student("王二",13)};//原数组
student []copyArray = new student[original.length];//拷贝数组
/**
* public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
* Object src:原数组
* int srcPos:开始位置
* Object dest:拷贝数组
* int destPos:开始位置
* int length:拷贝长度
*/
System.arraycopy(original,0,copyArray,0,original.length);
System.out.println("original[1] == copyArray[1]:"+ (original[1] == copyArray[1])); //输出true,元素内容并没有实际进行拷贝,浅拷贝
System.out.println("original == copyArray:"+ (original == copyArray)); //输出false,因为new了一个名指向原本数组内容,此数组名和原本数组名并不相同
original[0].name = "麻子";//修改原数组中元素,因为浅拷贝,所以会改变
for (student j : copyArray) {//输出拷贝的元素
System.out.print(j.toString()+" ");
}
System.out.println();
for (student j : original) {//输出原的元素
System.out.print(j.toString()+" ");
}
}
/*
输出结果
original[1] == copyArray[1]:true
original == copyArray:false
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
*/
4.Arrays.copyOf
浅拷贝,速度在clone和for之间
class student{
String name;
int age;
public student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public void cArray(){
student []original = new student[]{new student("张三",11),new student("李四",12),new student("王二",13)};//原数组
/**
* public static <Object> Object[] copyOf(Object[] original, int newLength)
* Object original:原数组
* int newLength:拷贝长度
* 返回一个数组对象
*/
student [] copyArray = Arrays.copyOf(original,original.length);
System.out.println("original[1] == copyArray[1]:"+ (original[1] == copyArray[1])); //输出true,元素内容并没有实际进行拷贝,浅拷贝
System.out.println("original == copyArray:"+ (original == copyArray)); //输出false,返回的数组名进行了new
original[0].name = "麻子";//修改原数组中元素,因为浅拷贝,所以会改变
for (student j : copyArray) {//输出拷贝的元素
System.out.print(j.toString()+" ");
}
System.out.println();
for (student j : original) {//输出原的元素
System.out.print(j.toString()+" ");
}
}
/*
输出结果
original[1] == copyArray[1]:true
original == copyArray:false
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
student{name='麻子', age=11} student{name='李四', age=12} student{name='王二', age=13}
*/