什么是深拷贝和浅拷贝?
在Java中,我们经常使用集合类来存储和操作对象。其中ArrayList是一种常用的动态数组(可变长度的数组)实现。但是在使用过程中,会遇到对象拷贝的问题:是深拷贝还是浅拷贝?
深拷贝和浅拷贝是针对对象进行复制、克隆的概念,假设有一个对象A,它有一个成员变量B,而B又有一个成员变量C,那么进行拷贝时,如果只是将A拷贝一份,那么B与其指向的C仍是原来A中的对象。此时,拷贝出来的对象与原对象虽然有相同的属性值,但却是两个相互独立的对象。这就是深拷贝。而只拷贝A对象,而B和C仍然是原对象A所指向的对象,则被称为浅拷贝。
ArrayList的浅拷贝和深拷贝
当我们进行ArrayList的拷贝时,Java提供两种方法:
- Object.clone()方法
- 通过循环新建对象复制所有元素
第一种方法是浅拷贝,由于ArrayList中的元素通常是对象引用,clone()方法只会复制对象的引用而不是对象本身,因此,如果我们对ArrayList中的元素进行修改操作,原列表和新列表中引用的同一个对象的内容都会改变。因此在我们使用ArrayList时,对于含有对象引用的数据结构,在使用clone()方法时应当特别小心。
下面我们通过两个示例来演示ArrayList的浅拷贝和深拷贝
示例一:浅拷贝
public class ShallowCopy {
public static void main(String[] args) {
//创建一个原始对象ArrayList
ArrayList<String> originalList = new ArrayList<>();
originalList.add("Apple");
originalList.add("Banana");
originalList.add("Cherry");
//进行对象的浅拷贝
ArrayList<String> clonedList = (ArrayList<String>)originalList.clone();
//修改拷贝后的对象
clonedList.set(1, "Watermelon");
//输出结果
System.out.println("Original ArrayList: " + originalList);
System.out.println("Cloned ArrayList: " + clonedList);
}
}
输出结果:
Original ArrayList: [Apple, Banana, Cherry]
Cloned ArrayList: [Apple, Watermelon, Cherry]
可以发现,尽管我们只是修改了拷贝后的对象,但原始对象的内容也随之改变了。
示例二:深拷贝
class Person implements Cloneable {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "[name=" + name + ", age=" + age + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class DeepCopy {
public static void main(String[] args) throws CloneNotSupportedException {
//创建一个原始对象ArrayList
ArrayList<Person> originalList = new ArrayList<>();
originalList.add(new Person("Tom", 20));
originalList.add(new Person("Jack", 21));
originalList.add(new Person("Jerry", 22));
//进行对象的深拷贝
ArrayList<Person> clonedList = new ArrayList<>();
for (Person person : originalList) {
clonedList.add((Person)person.clone());
}
//修改拷贝后的对象
clonedList.get(1).age = 25;
//输出结果
System.out.println("Original ArrayList: " + originalList);
System.out.println("Cloned ArrayList: " + clonedList);
}
}
输出结果:
Original ArrayList: [[name=Tom, age=20], [name=Jack, age=21], [name=Jerry, age=22]]
Cloned ArrayList: [[name=Tom, age=20], [name=Jack, age=25], [name=Jerry, age=22]]
可以发现,尽管我们只是修改了拷贝后的对象,但原始对象的内容没有发生变化。这证明我们成功进行了深拷贝。
总之,当我们需要对包含对象引用的数据结构进行拷贝时,应该根据实际需要选择浅拷贝还是深拷贝。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java ArrayList的深拷贝与浅拷贝问题 - Python技术站