结合场景,浅谈深浅度拷贝

   有两段代码是这样的:

A段:

List<String> list1 = new ArrayList<>();
Bear B = new Bear();
for(Apple apple : apples){
	B.url = apple.url;
	B.content = apple.content;
	list1.add(Bear);
}

B段:

List<String> list1 = new ArrayList<>();
for(Apple apple : apples){
Bear B = new Bear();
	B.url = apple.url;
	B.content = apple.content;
	list1.add(Bear);
}

显而易见,这两段代码的区别在于Bear对象的创建的位置不同,第一段代码里面,先创建了一个 Bear 对象 B,然后在循环中不断更新 B 的属性,并将同一个 B 对象多次添加到 list1 中。由于 list1 中存储的是对象的引用,因此最终 list1 中存储的是多个指向同一个 Bear 对象的引用。

而第二段代码中,我们在每次循环中都创建了一个新的 Bear 对象 B,并将其添加到 list1 中。因此,list1 中存储的是多个不同的 Bear 对象的引用。

所以,其实两次list的存储的Bear对象结果会是不同的,第一段代码存了一堆一样的Bear,那么问题来了:我想不重复创建Bear对象,但是也能达到第二段效果,应该怎么做?

答案是使用深度拷贝;

在修复代码之前,深浅度拷贝的定义我们复习下:

浅拷贝(Shallow Copy):

  • 浅拷贝是指在复制对象时,只复制对象本身和其内部引用的对象的引用,而不复制引用的对象本身。
  • 在浅拷贝中,新对象和原对象共享内部引用的对象,即新对象和原对象的引用指向同一个内部对象。
  • 如果原对象的属性是基本数据类型,那么浅拷贝会复制这些属性的值;如果原对象的属性是引用类型,那么浅拷贝只会复制引用,而不会复制引用指向的对象。

深度拷贝(Deep Copy):

  • 深度拷贝是指在复制对象时,不仅复制对象本身,还会递归复制对象内部引用的对象,直到所有引用的对象都被复制。
  • 在深度拷贝中,新对象和原对象的所有引用对象都是独立的,即新对象和原对象的引用指向不同的内部对象。
  • 无论原对象的属性是基本数据类型还是引用类型,深度拷贝都会复制所有属性的值或引用指向的对象。

原理比较:

  • 浅拷贝只复制对象本身和其内部引用的对象的引用,因此新对象和原对象共享内部引用的对象,可能会导致对象之间的状态相互影响。
  • 深度拷贝会递归复制对象内部引用的对象,确保新对象和原对象的所有引用对象都是独立的,避免对象之间的状态相互影响。

那么好,我们基于该原理改造下我们的第一段代码:

首先需要重写Bear对象,重写clone方法:

public class Bear implement Clone{
    private String url;
    private String content;

    //构造函数等省略

    @Override
    public Bear clone(){
        try{
             Bear cloned = (Bear) super.clone(); // 首先调用父类的 clone 方法进行浅拷贝
            // 对象的属性进行深度拷贝
            cloned.url = new String(this.url);
            cloned.content = new String(this.content);
            return cloned; 
        }catch(CloneNotSupportedException e){
            throw new AssertionError();
        }

    }

}

写完Bear类的clone方法后,就可以用它的clone方法来做对象复制,最终第一段代码改写如下:

List<String> list1 = new ArrayList<>();
Bear originalBear = new Bear(); // 假设有一个原始的 Bear 对象
for(Apple apple : apples){
    Bear clonedBear = originalBear.clone(); // 使用克隆方法创建新的 Bear 对象
    clonedBear.url = apple.url;
    clonedBear.content = apple.content;
    list1.add(clonedBear);
}

这样修改后,可以避免多次创建新对象,同时确保 list1 中加载不同的 Bear 对象。

相关推荐

  1. 结合场景深浅拷贝

    2024-05-11 06:58:12       9 阅读
  2. 深度学习的学习方法

    2024-05-11 06:58:12       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-11 06:58:12       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-11 06:58:12       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-11 06:58:12       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-11 06:58:12       20 阅读

热门阅读

  1. Spring Boot + Logback 实现日志记录写入文件

    2024-05-11 06:58:12       10 阅读
  2. vueConfig

    2024-05-11 06:58:12       7 阅读
  3. MES系统助力离散制造行业智能制造升级

    2024-05-11 06:58:12       11 阅读
  4. Django 和 Spring Boot

    2024-05-11 06:58:12       9 阅读
  5. 微信原生小程序封装网络请求wx.request

    2024-05-11 06:58:12       11 阅读
  6. mysql(一)

    2024-05-11 06:58:12       9 阅读
  7. 未来趋势系列 篇一:AI主题全景分析和股票梳理

    2024-05-11 06:58:12       9 阅读