实现深拷贝和浅拷贝有哪些方式
时间: 2024-04-18 13:10:23 浏览: 78
实现深拷贝和浅拷贝的方式有以下几种:
1. 浅拷贝:直接赋值,将一个对象的引用赋给另一个对象,两个对象共享同一块内存,修改一个对象会影响另一个对象。
2. 浅拷贝:Object.assign(),用于复制一个或多个源对象的所有可枚举属性到目标对象中,如果属性值是对象,则只复制引用。
3. 浅拷贝:展开运算符(...),用于将一个数组或对象“展开”成多个元素,浅拷贝只复制引用。
4. 深拷贝:JSON.parse(JSON.stringify()),将一个对象转换为JSON字符串,再将JSON字符串转换为新的对象,适用于对象没有函数、循环引用等情况。
5. 深拷贝:递归拷贝每个属性,如果属性是对象则递归拷贝,如果是基本类型则直接赋值。但需要注意循环引用的情况。
相关问题
深拷贝和浅拷贝,实现深拷贝的方式
深拷贝和浅拷贝是在编程中用于复制对象的两种不同方式。
浅拷贝是指创建一个新对象,将原始对象的成员变量的值复制到新对象中。这意味着新对象和原始对象共享相同的内存地址,当其中一个对象修改了共享的成员变量时,另一个对象也会受到影响。
深拷贝是指创建一个新对象,并将原始对象的所有成员变量的值复制到新对象中。与浅拷贝不同,深拷贝会为新对象分配独立的内存空间,使得新对象和原始对象完全独立,互不影响。
实现深拷贝的方式有多种,以下是几种常见的方式:
1. 手动实现深拷贝:通过逐个复制原始对象的成员变量,创建新的对象并赋值。对于引用类型的成员变量,需要递归地进行深拷贝。
2. 使用拷贝构造函数:在类中定义一个拷贝构造函数,通过该构造函数创建新对象时,将原始对象的成员变量值复制到新对象中。同样需要对引用类型进行递归深拷贝。
3. 使用序列化和反序列化:将原始对象序列化为字节流,然后再反序列化为新对象。这种方式可以实现深拷贝,但需要确保对象及其成员变量都是可序列化的。
4. 使用标准库提供的深拷贝函数:一些编程语言的标准库提供了深拷贝函数,可以直接使用这些函数来实现深拷贝。
如何实现深拷贝和浅拷贝
深拷贝和浅拷贝是针对对象(包括数组)的复制操作,它们的区别在于复制出来的新对象与原对象之间的关系不同。
浅拷贝只复制对象本身,而不会复制对象内部的子对象,新对象和原对象之间共享子对象。例如,对于一个包含引用类型成员变量的对象,浅拷贝会复制成员变量的引用,而不会复制成员变量所指向的对象。浅拷贝可以通过对象的 clone() 方法实现。
深拷贝则会复制整个对象及其内部所有子对象,新对象和原对象之间完全独立。例如,对于一个包含引用类型成员变量的对象,深拷贝会递归复制成员变量所指向的对象。深拷贝可以通过序列化和反序列化实现,或者手动递归复制对象及其子对象。
以下是 Java 中的示例代码:
浅拷贝:
```java
public class Person implements Cloneable {
public String name;
public Address address;
@Override
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
}
public class Address {
public String city;
}
Person p1 = new Person();
p1.name = "Alice";
p1.address = new Address();
p1.address.city = "Shanghai";
Person p2 = p1.clone();
p2.name = "Bob";
p2.address.city = "Beijing"; // 修改 p2 的 address
System.out.println(p1.name); // "Alice"
System.out.println(p1.address.city); // "Beijing",p1 和 p2 的 address 引用同一个对象
```
深拷贝:
```java
public class Person implements Serializable {
public String name;
public Address address;
public Person deepClone() throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (Person) ois.readObject();
}
}
public class Address implements Serializable {
public String city;
}
Person p1 = new Person();
p1.name = "Alice";
p1.address = new Address();
p1.address.city = "Shanghai";
Person p2 = p1.deepClone();
p2.name = "Bob";
p2.address.city = "Beijing"; // 修改 p2 的 address
System.out.println(p1.name); // "Alice"
System.out.println(p1.address.city); // "Shanghai",p1 和 p2 的 address 引用不同的对象
```
阅读全文