浅拷贝和深拷贝的整理


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 浅拷贝:
 * 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制。
 * 如果该字段是引用类型的话,则复制引用但不复制引用的对象,因此,原始对象及其副本引用同一个对象。
 * 实现浅拷贝的方式:
 * 对象实现cloneable接口,实现clone()方法
 *
 * 深拷贝:
 * 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,无论该字段是值类型还是引用类型都是复制独立的一份。
 * 当你修改其中一个对象的任何内容时,都不会影响另一个对象的内容。
 *
 * 实现深拷贝的方法
 * 1)让每一个引用类型属性内部都重写clone()方法。此方法有个缺点:如果有多个引用类型,必须重写多次。
 * 2)利用序列化
 * 序列化是将对象写到流中便于传输,而反序列化则是把对象从流中读取出来。这里写到流中的对象则是原始对象的一个拷贝,因为原始对象还存在
 * JVM中,所有利用对象的序列化产生克隆对象,通过反序列化获取这个对象。
 *
 */
public class TestCopy {

    public static void main(String[] args) throws Exception{
        Person p1=new Person("sunyuhua",22);
        p1.setAddress("山东省","潍坊市");
        System.out.println(p1);
        System.out.println(p1.getPname().hashCode());
        Person p2=(Person)p1.clone();
        System.out.println(p2);
        System.out.println(p2.getPname().hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.equals(p2));
        p1.display("p1");
        p2.display("p2");
        p2.setAddress("上海","浦东");
        System.out.println(p1.getPname().hashCode());
        System.out.println(p2.getPname().hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.equals(p2));
        p1.display("p1");
        p2.display("p2");

        System.out.println("深拷贝深拷贝深拷贝深拷贝深拷贝深拷贝");
        DeepPerson deepPerson1=new DeepPerson("sunyuhua",22);
        deepPerson1.setAddress("山东省","潍坊市");
        System.out.println(deepPerson1);
        System.out.println(deepPerson1.getPname().hashCode());
        DeepPerson deepPerson2=(DeepPerson)deepPerson1.clone();
        System.out.println(deepPerson2);
        System.out.println(deepPerson2.getPname().hashCode());
        System.out.println(deepPerson1==deepPerson2);
        System.out.println(deepPerson1.equals(deepPerson2));
        deepPerson1.display("deepPerson1");
        deepPerson2.display("deepPerson2");
        deepPerson2.setAddress("上海","浦东");
        System.out.println(deepPerson1.getPname().hashCode());
        System.out.println(deepPerson2.getPname().hashCode());
        System.out.println(deepPerson1==deepPerson2);
        System.out.println(deepPerson1.equals(deepPerson2));
        p1.display("deepPerson1");
        p2.display("deepPerson2");
        System.out.println("深拷贝深拷贝深拷贝深拷贝深拷贝深拷贝");
        System.out.println("利用序列化利用序列化利用序列化利用序列化");
        Person person1=new Person("sunyuhua",22);
        person1.setAddress("山东省","潍坊市");
        System.out.println(person1);
        System.out.println(person1.getPname().hashCode());
        Person person2=(Person) deepClone(person1);
        System.out.println(person2);
        System.out.println(person2.getPname().hashCode());
        System.out.println(person1==person2);
        System.out.println(person1.equals(person2));
        deepPerson1.display("person1");
        deepPerson2.display("person2");
        deepPerson2.setAddress("上海","浦东");
        System.out.println(person1.getPname().hashCode());
        System.out.println(person2.getPname().hashCode());
        System.out.println(person1==person2);
        System.out.println(person1.equals(person2));
        p1.display("person1");
        p2.display("person2");
    }

    /**
     * 对象深复制的方法
     * @param person
     * @return
     * @throws Exception
     */
    public static Object deepClone(Person person) throws Exception{
        //将对象进行序列化
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(person);
        //将对象反序列化
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
        return objectInputStream.readObject();
    }

}

/**
 * 实现浅拷贝
 */
@Data
public class Person implements Cloneable, Serializable {
    public String pname;
    public int page;
    public Address address;

    public Person(String pname,int page){
        this.pname=pname;
        this.page=page;
        this.address=new Address();
    }

    public void setAddress(String provices,String city){
        address.setAddress(provices,city);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public void display(String name){
        System.out.println("name="+pname+",page="+page+"address="+address.toString());
    }
}

package com.chen.www.chendemo.objectCopy;

import java.io.Serializable;

public class Address implements Serializable {
    private String provices;
    private String city;
    public void setAddress(String provices,String city){
        this.provices=provices;
        this.city=city;
    }

    @Override
    public String toString() {
        return "address==provices="+provices+"city="+city;
    }
}


/**
 * 让每一个引用类型属性内部都重写clone()方法。
 * 既然引用类型不能实现深拷贝,那么我们将每个引用类型都拆分为基本类型,分别进行浅拷贝。
 */
public class DeepAddress implements Cloneable{
    private String provices;
    private String city;
    public void setAddress(String provices,String city){
        this.provices=provices;
        this.city=city;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "address==provices="+provices+"city="+city;
    }
}


import lombok.Data;

@Data
public class DeepPerson implements Cloneable{
    public String pname;
    public int page;
    public DeepAddress deepAddress;

    public DeepPerson(String pname,int page){
        this.pname=pname;
        this.page=page;
        this.deepAddress=new DeepAddress();
    }

    public void setAddress(String provices,String city){
        deepAddress.setAddress(provices,city);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        DeepPerson person=(DeepPerson)super.clone();
        person.deepAddress=(DeepAddress)deepAddress.clone();
        return person;
    }

    public void display(String name){
        System.out.println("name="+pname+",page="+page+"address="+deepAddress.toString());
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在编程中,对象和数组的深拷贝涉及到数据结构的副本创建,确保新创建的对象与原对象独立,即使原对象发生改变也不会影响副本。这里有几种常见的深拷贝方式: 1. **浅拷贝(Shallow Copy)**: 对于简单类型(如基本数据类型)或值类型,拷贝的是它们的值。对于复杂类型如数组或对象,浅拷贝实际上是创建了一个引用,两个变量指向的是同一个内存地址。这意味着对其中一个的修改会影响到另一个。 2. **深拷贝(Deep Copy)**: - **复制数组**:对于数组,可以逐个元素地进行深拷贝,创建一个新的数组并填充每个元素的深拷贝。例如,在JavaScript中可以使用`JSON.parse(JSON.stringify(array))`来实现。 - **复制对象**: a. 使用构造函数:创建新对象,然后递归遍历原对象,为每个属性创建新的值,而不是引用。例如在JavaScript中,`function deepCopy(obj) { return new obj.constructor(obj); }`。 b. 使用`Object.assign()`和扩展运算符...:结合使用,创建一个新的对象,并将所有属性从源对象复制过来,但不会创建循环引用。但是这种方法不适用于原型链中的对象。 c. 库方法:有些编程语言有现成的库函数或模块可以直接完成深拷贝操作,比如Python的`copy.deepcopy()`。 3. **深度克隆(Deep Cloning)**: 术语"深度克隆"通常用于描述深度复制的过程,特别是在讨论复杂的数据结构,如树、图或对象树时。 **相关问题**: 1. 浅拷贝深拷贝的主要区别是什么? 2. 如何在JavaScript中避免对象属性的引用冲突进行深拷贝? 3. 如果数组中的元素是对象,应该如何正确地进行深拷贝
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MonkeyKing.sun

对你有帮助的话,可以打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值