数组拷贝
首先看看深拷贝和浅拷贝的概念,在 Java 中,除了基本数据类型之外,还有引用数据类型。而一般使用 " = " 做赋值操作的时候。对于基本数据类型,实际上是拷贝的它的值,但是对于对象而言,其实赋值的只是这个对象的引用,他们实际上还是指向的同一个对象。而浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。
1)浅拷贝:对基本数据类型进行值传递,对引用数据类型进行了引用传递
2)深拷贝:对基本数据类型进行值传递,对引用数据类型,则创建了一个新的对象,并复制了其内容
1 for循环(数值拷贝)
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
int[] arraycopy = new int[5];
for(int i=0;i<array.length;i++){
arraycopy[i]=array[i];
}
arraycopy[0]=90;
for(int x:array){
System.out.print(x+" "); //1 2 3 4 5
}
System.out.println();
for(int x:arraycopy){
System.out.print(x+" ");//90 2 3 4 5
}
}
2 Clone()
(1)数值拷贝
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
int[] arraycopy = new int[5];
arraycopy=array.clone();
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(arraycopy));
System.out.println("*****************");
array[0]=100;
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(arraycopy));
}
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[100, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
(2)数组引用类型拷贝
class Student{
private int age=10;
public Student(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Student[] students=new Student[2];
students[0]=new Student(15);
students[1]=new Student(25);
Student[] teachers = students.clone();
for(Student x:students){
System.out.print(x.getAge()+" ");
}
System.out.println();
for(Student x:teachers){
System.out.print(x.getAge()+" ");
}
System.out.println();
System.out.println("************");
students[0].setAge(99);
for(Student x:students){
System.out.print(x.getAge()+" ");
}
System.out.println();
for(Student x:teachers){
System.out.print(x.getAge()+" ");
}
}
}
15 25
15 25
99 25
99 25
(3)对象之间的拷贝
java.lang.Object类的clone()方法为protected类型,不可直接调用,被克隆的类要实现Cloneable接口;然后在该类中覆盖clone()方法,并且在该clone()方法中调用super.clone()。
class Money {
public double money = 12.5;
}
class Person implements Cloneable{
public String name;
public Money m;
public Person() {
this.m = new Money();
}
// 重写clone方法:Object
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
Person person2 = (Person)person.clone();
System.out.println(person.m.money);
System.out.println(person2.m.money);
System.out.println("===================");
person2.m.money = 99.9;
System.out.println(person.m.money);
System.out.println(person2.m.money);
}
结果显示此时的clone为浅拷贝。
12.5
12.5
99.9
99.9
为了实现深拷贝,可以继续使用clone方法,将其内的引用类型变量m进行clone
class Money implements Cloneable{
double money = 12.5;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public String name;
public Money m;
public Person() {
this.m = new Money();
}
//重写clone方法:Object
@Override
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
Person per = (Person) super.clone();
per.m = (Money)this.m.clone();
return per;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
Person person2 = (Person)person.clone();
System.out.println(person.m.money);
System.out.println(person2.m.money);
System.out.println("===================");
person2.m.money = 99.9;
System.out.println(person.m.money);
System.out.println(person2.m.money);
}
}
结果显示为深拷贝:
12.5
12.5
12.5
99.9
3 System.arraycopy()
class Student{
private int age=10;
public Student(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Student[] students=new Student[2];
students[0]=new Student(15);
students[1]=new Student(25);
Student[] teachers = new Student[2];
System.arraycopy(students,0,teachers,0,students.length);
for(Student x:students){
System.out.print(x.getAge()+" ");
}
System.out.println();
for(Student x:teachers){
System.out.print(x.getAge()+" ");
}
System.out.println();
System.out.println("************");
students[0].setAge(99);
for(Student x:students){
System.out.print(x.getAge()+" ");
}
System.out.println();
for(Student x:teachers){
System.out.print(x.getAge()+" ");
}
}
}
浅拷贝:
15 25
15 25
99 25
99 25
//System.arraycopy()方法java源代码中的代码
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
native方法为本地方法,效率较高。
src :源地址
srcPos:源地址开始位置
dest:目的地
destPos:目的地的开始位置
length:拷贝的长度
4 Arrays.copyOf()方法
底层调用的是System.arraycopy(),Arrays.copyOf(源数组,指定数组长度),Arrays.copyOf()方法会产生一个新的对象,但依然是浅拷贝。
class Student{
private int age=10;
public Student(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Student[] students=new Student[2];
students[0]=new Student(15);
students[1]=new Student(25);
Student[] teachers =
Arrays.copyOf(students,students.length);
for(Student x:students){
System.out.print(x.getAge()+" ");
}
System.out.println();
for(Student x:teachers){
System.out.print(x.getAge()+" ");
}
System.out.println();
System.out.println("************");
students[0].setAge(99);
for(Student x:students){
System.out.print(x.getAge()+" ");
}
System.out.println();
for(Student x:teachers){
System.out.print(x.getAge()+" ");
}
}
}
15 25
15 25
99 25
99 25