java中深复制知识点详解

 更新时间:2020年12月27日 10:13:05   作者:小妮浅浅  
在本篇文章里小编给大家整理了关于java中深复制知识点详解内容,有需要的朋友们可以学习下。

在正式开始深复制的讲解之前,我们先来理解一下概念。假设一个物品需要批量生产,但是这个物品还配有赠品,生产的时候需要把赠品也列在计划内。所谓深复制的原理就是这样,我们不能只复制属性,包括引用之类的附带也需要被复制。下面小编就为大家带来深复制的两种不同方法。

1.序列化实现

如下为谷歌Gson序列化HashMap,实现深度复制的例子:

public class CopyDeepMapTest {
  public static void main(String[] args) {
    HashMap<Integer, User> userMap = new HashMap<>();
    userMap.put(1, new User("jay", 26));
    userMap.put(2, new User("fany", 25));
    //Shallow clone
    Gson gson = new Gson();
    String jsonString = gson.toJson(userMap);
    Type type = new TypeToken<HashMap<Integer, User>>(){}.getType();
    HashMap<Integer, User> clonedMap = gson.fromJson(jsonString, type);
    //Same as userMap
    System.out.println(clonedMap);
    System.out.println("\nChanges DO NOT reflect in other map \n");
    //Change a value is clonedMap
    clonedMap.get(1).setName("test");
    //Verify content of both maps
    System.out.println(userMap);
    System.out.println(clonedMap);
  }
}

运行结果:

{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
Changes DO NOT reflect in other map 
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}

从运行结果看出,对cloneMap修改,userMap没有被改变,所以是深度复制。

2.list深复制

两个list数据相同但是地址值不同,A和B是独立的两个list,A改变了B不会改变,B改变了A也不会改变

深复制的工具类方法:

public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
@SuppressWarnings("unchecked")
List<T> dest = (List<T>) in.readObject();
return dest;
}

关于深拷贝的一个扩展实例:

public class YuelyLog implements Serializable,Cloneable {
  private Attachment attachment;
  private String name;
  private String date;

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

  public Attachment getAttachment() {
    return attachment;
  }

  public void setAttachment(Attachment attachment) {
    this.attachment = attachment;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getDate() {
    return date;
  }

  public void setDate(String date) {
    this.date = date;
  }

  /**
   * 使用序列化技术实现深拷贝
   * @return
   */
  public YuelyLog deepClone() throws IOException,ClassNotFoundException{
    //将对象写入流中
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
    objectOutputStream.writeObject(this);
    //从流中取出
    ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
    ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
    return (YuelyLog)objectInputStream.readObject();

  }
}

相关文章

  • 一文搞懂Java中的抽象类和接口到底是什么

    一文搞懂Java中的抽象类和接口到底是什么

    在类中没有包含足够的信息来描绘一个具体的对象,这样的类称为抽象类,接口是Java中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成,本文给大家介绍Java抽象类和接口,感兴趣的朋友一起看看吧
    2022-04-04
  • Java中final关键字的深入探究

    Java中final关键字的深入探究

    这篇文章主要给大家介绍了关于Java中final关键字的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • 剑指Offer之Java算法习题精讲二叉树专题篇上

    剑指Offer之Java算法习题精讲二叉树专题篇上

    跟着思路走,之后从简单题入手,反复去看,做过之后可能会忘记,之后再做一次,记不住就反复做,反复寻求思路和规律,慢慢积累就会发现质的变化
    2022-03-03
  • SpringBoot + SpringSecurity 短信验证码登录功能实现

    SpringBoot + SpringSecurity 短信验证码登录功能实现

    这篇文章主要介绍了SpringBoot + SpringSecurity 短信验证码登录功能实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • IDEA最新激活码2021(IDEA2020.3.2最新永久激活方法)

    IDEA最新激活码2021(IDEA2020.3.2最新永久激活方法)

    这篇文章主要介绍了IDEA最新激活码2021(IDEA2020.3.2最新永久激活方法),本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 解决没有@RunWith 和 @SpringBootTest注解或失效问题

    解决没有@RunWith 和 @SpringBootTest注解或失效问题

    这篇文章主要介绍了解决没有@RunWith 和 @SpringBootTest注解或失效问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • SpringCloud+MyBatis分页处理(前后端分离)

    SpringCloud+MyBatis分页处理(前后端分离)

    这篇文章主要为大家详细介绍了SpringCloud+MyBatis分页处理,前后端分离,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 解决idea找不到setting.xml文件的问题

    解决idea找不到setting.xml文件的问题

    这篇文章主要介绍了解决idea找不到setting.xml文件的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • springmvc用于方法鉴权的注解拦截器的解决方案代码

    springmvc用于方法鉴权的注解拦截器的解决方案代码

    这篇文章主要介绍了springmvc用于方法鉴权的注解拦截器的解决方案代码,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • Spring中@RefreshScope注解的处理方法详解

    Spring中@RefreshScope注解的处理方法详解

    这篇文章主要介绍了Spring中@RefreshScope注解的处理方法详解,spring启动时会调用ClassPathBeanDefinitionScanner.java类中的doScan()对包路径下的所有class进行扫描,获取bean的定义,同时对bean的@RefreshScope(@Scope的父类)进行处理,需要的朋友可以参考下
    2023-10-10

最新评论