深拷贝|浅拷贝
目录
1. 深拷贝(Deep Copy)
2. 浅拷贝(Shallow Copy)
3. 深拷贝和浅拷贝的区别
4. 示例代码
浅拷贝示例
深拷贝示例
5.常用的方法
1.Java Object.clone() 方法
2.序列化与反序列化
6.Spring Boot 中的常用方法
使用 SerializationUtils
使用 ModelMapper 或 MapStruct
7.Hutool 工具类
浅拷贝
深拷贝
8.Guava 中的相关工具类
总结
深拷贝和浅拷贝是对象复制的两种方式,它们在处理引用类型的字段时存在显著差异。下面将详细介绍它们的含义、区别,并提供代码示例。
1. 深拷贝(Deep Copy)
-
定义:深拷贝创建一个新对象,并且复制原对象中的所有字段,包括引用类型的字段。对于每个引用类型的字段,它都会创建一个新的实例,确保源对象和目标对象之间没有任何共享的引用。
-
递归地复制所有子对象。即使原始对象或拷贝对象修改其子对象,也不会互相影响。
-
-
特点:
-
基本数据类型的值会被复制。
-
引用数据类型的对象会被完全独立地复制。
-
2. 浅拷贝(Shallow Copy)
-
定义:浅拷贝创建一个新对象,该对象与原对象具有相同的值,但对引用类型字段只会复制引用地址,而不复制实际的对象。这意味着原对象和新对象的引用类型属性指向同一块内存。
-
不递归地复制对象所引用的子对象。它仅复制对象的基本数据类型和对引用类型的引用,因此原始对象和拷贝对象中对引用类型的修改会相互影响。
-
-
特点:
-
基本数据类型的值会被复制。
-
引用数据类型的对象会共享同一个实例。
-
3. 深拷贝和浅拷贝的区别
| 特性 | 浅拷贝 | 深拷贝 |
|---|---|---|
| 对基本类型 | 复制其值 | 复制其值 |
| 对引用类型 | 复制引用(共同使用同一对象) | 复制对象(各自独立的对象) |
| 影响 | 修改一个对象的引用类型字段会影响另一个对象 | 修改一个对象不会影响另一个对象 |
4. 示例代码
浅拷贝示例
class Address {String city;
public Address(String city) {this.city = city;}
}
class Person implements Cloneable {String name;Address address;
public Person(String name, Address address) {this.name = name;this.address = address;}
@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 浅拷贝}
}
public class ShallowCopyExample {public static void main(String[] args) throws CloneNotSupportedException {Address address = new Address("New York");Person person1 = new Person("Alice", address);Person person2 = (Person) person1.clone(); // 浅拷贝
System.out.println("Before modification:");System.out.println("Person1 Address: " + person1.address.city); // 输出: New YorkSystem.out.println("Person2 Address: " + person2.address.city); // 输出: New York
// 修改 person2 的地址person2.address.city = "Los Angeles";
System.out.println("After modification:");System.out.println("Person1 Address: " + person1.address.city); // 输出: Los Angeles (共享同一引用)System.out.println("Person2 Address: " + person2.address.city); // 输出: Los Angeles}
}
深拷贝示例
class Address {String city;
public Address(String city) {this.city = city;}
// 深拷贝方法public Address deepCopy() {return new Address(this.city);}
}
class Person {String name;Address address;
public Person(String name, Address address) {this.name = name;this.address = address;}
// 深拷贝方法public Person deepCopy() {return new Person(this.name, this.address.deepCopy());}
}
public class DeepCopyExample {public static void main(String[] args) {Address address = new Address("New York");Person person1 = new Person("Alice", address);Person person2 = person1.deepCopy(); // 深拷贝
System.out.println("Before modification:");System.out.println("Person1 Address: " + person1.address.city); // 输出: New YorkSystem.out.println("Person2 Address: " + person2.address.city); // 输出: New York
// 修改 person2 的地址person2.address.city = "Los Angeles";
System.out.println("After modification:");System.out.println("Person1 Address: " + person1.address.city); // 输出: New York (不受影响)System.out.println("Person2 Address: " + person2.address.city); // 输出: Los Angeles}
}
5.常用的方法
1.Java Object.clone() 方法
-
Object类提供的clone()方法可以用于实现浅拷贝。 -
需要实现
Cloneable接口,并重写clone()方法。
2.序列化与反序列化
-
对象可以通过序列化为字节流,再反序列化为新对象。这种方式可以实现深拷贝。
-
需要实现
Serializable接口。
6.Spring Boot 中的常用方法
在 Spring Boot 中,通常使用以下方式来实现深拷贝:
使用 SerializationUtils
import org.springframework.util.SerializationUtils;
byte[] bytes = SerializationUtils.serialize(originalObject);
MyObject copiedObject = (MyObject) SerializationUtils.deserialize(bytes);
使用 ModelMapper 或 MapStruct
ModelMapper 和 MapStruct 都可以用来轻松地进行对象之间的映射,借此实现深拷贝。
7.Hutool 工具类
Hutool 提供了简单易用的工具类,可以进行深拷贝和浅拷贝:
浅拷贝
Person copy = ShallowUtil.clone(original);
深拷贝
Person deepCopy = CloneUtil.clone(original);
8.Guava 中的相关工具类
Guava 提供了 Immutable 集合来避免可变性,虽然不是直接的拷贝方法,但可以帮助管理不可变对象。
-
ImmutableList
、ImmutableSet和ImmutableMap 用于创建不可变的集合,这样可以避免浅拷贝的问题。 -
不可变集合在创建后无法更改,这使得它们特别适合于多线程环境和函数式编程风格。
import com.google.common.collect.ImmutableList;
public class ImmutableListExample {public static void main(String[] args) {// 创建一个不可变列表ImmutableList<String> immutableList = ImmutableList.of("Apple", "Banana", "Cherry");
System.out.println(immutableList);
// 下面的操作会抛出 UnsupportedOperationException,因为该列表是不可变的// immutableList.add("Date"); // Uncommenting this line will throw an exception}
}
import com.google.common.collect.ImmutableSet;
public class ImmutableSetExample {public static void main(String[] args) {// 创建一个不可变集合ImmutableSet<String> immutableSet = ImmutableSet.of("Red", "Green", "Blue");
System.out.println(immutableSet);
// 下面的操作会抛出 UnsupportedOperationException,因为该集合是不可变的// immutableSet.add("Yellow"); // Uncommenting this line will throw an exception}
}
import com.google.common.collect.ImmutableMap;
public class ImmutableMapExample {public static void main(String[] args) {// 创建一个不可变映射ImmutableMap<String, Integer> immutableMap = ImmutableMap.of("Alice", 30,"Bob", 25,"Charlie", 35);
System.out.println(immutableMap);
// 下面的操作会抛出 UnsupportedOperationException,因为该映射是不可变的// immutableMap.put("Dave", 40); // Uncommenting this line will throw an exception}
}
总结
-
浅拷贝和深拷贝分别适用于不同的场景。
-
根据需要选择合适的拷贝方法,并利用现有的框架和库简化工作。
相关文章:
深拷贝|浅拷贝
目录 1. 深拷贝(Deep Copy) 2. 浅拷贝(Shallow Copy) 3. 深拷贝和浅拷贝的区别 4. 示例代码 浅拷贝示例 深拷贝示例 5.常用的方法 1.Java Object.clone() 方法 2.序列化与反序列化 6.Spring Boot 中的常用方法 使用 Se…...
图像处理-掩码
文章目录 一、简介二、主要用途三、代码实现四、掩码优缺点1.优点2.缺点 一、简介 在图像处理中,掩码(Mask)是一种特殊的图像,用于指定对原始图像进行操作的区域。掩码通常是二值图像(即图像上的每个像素只有两个可能…...
[2025]基于微信小程序慢性呼吸系统疾病的健康管理(源码+文档+解答)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
react之jsx基础(1)概念和本质
文章目录 JSX 的基本概念1. **语法**2. **表达式**3. **属性**4. **子元素** JSX 的编译过程1. **转换成 JavaScript**2. **React 元素** JSX 的实际应用1. **组件定义**2. **组件嵌套** 总结 当然,以下是对 JSX 的详细讲解,包括其基本概念、语法、编译过…...
sqli-labs靶场自动化利用工具——第13关
文章目录 概要整体架构流程技术细节执行效果小结 概要 Sqli-Labs靶场对于网安专业的学生或正在学习网安的朋友来说并不陌生,或者说已经很熟悉。那有没有朋友想过自己开发一个测试脚本能实现自动化化测试sqli-labs呢?可能有些人会说不是有sqlmap&#…...
大舍传媒:尼日利亚传统新闻媒体宣传助力新兴行业蓬勃发展
大舍传媒:尼日利亚传统新闻媒体宣传助力新兴行业蓬勃发展 在全球化的浪潮下,媒体作为信息传播的重要渠道,对于促进行业发展和推动社会进步扮演着举足轻重的角色。特别是在非洲大陆上人口最多、经济最发达的国家——尼日利亚,传统…...
ISSTA 2024盛大开幕:中国学者的录取数和投稿量均位列第一
随着夏日的尾声,全球软件测试领域的专家和学者齐聚在奥地利维也纳。共同参与这场科技盛宴——ISSTA 2024。这场国际会议正如火如荼地进行中,吸引了来自世界各地的专业人士参与。 会议实况: 9月16日与17日,大会安排了丰富的社交活…...
HttpMediaTypeNotAcceptableException: No acceptable representation问题解决方法
Background org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation HttpMediaTypeNotAcceptableException: No acceptable representation 异常通常发生在Web应用程序中,客户端请求了一个资源,但是…...
Scrapy爬虫框架 Pipeline 数据传输管道
在网络数据采集领域,Scrapy 是一个非常强大的框架,而 Pipeline 是其中不可或缺的一部分。它允许我们在数据处理的最后阶段对抓取的数据进行进一步的处理,如清洗、存储等操作。 本教程将详细介绍如何在 Scrapy 中使用 Pipeline,帮…...
vim的 配置文件
vim 的配置文件名是vimrc,共有两个,一个是公共的、所有用户的vimrc,一个是私有的、个人的.vimrc。个人的配置文件是隐藏的,不进行配置的话一般是没有这个文件的,需要自己创建.vimrc 公共配置文件位于 :/etc/vim/vimrc…...
Golang | Leetcode Golang题解之第403题青蛙过河
题目: 题解: func canCross(stones []int) bool {n : len(stones)dp : make([][]bool, n)for i : range dp {dp[i] make([]bool, n)}dp[0][0] truefor i : 1; i < n; i {if stones[i]-stones[i-1] > i {return false}}for i : 1; i < n; i {…...
前端项目使用js将dom生成图片、PDF
在进行下方操作前,请你先安装 html2canvas 和 jspdf 包。 1、使用html2canvas将dom元素生成图片 // 获取要转换的dom const ele document.getElementById("dom"); // 生成canvas对象 let canvas await html2canvas(ele); 2、生成PDF对象,将…...
在 Red Hat 上安装 SQL Server 2022 并创建数据库
适用于: SQL Server - Linux 本快速入门介绍如何在 Red Hat Enterprise Linux (RHEL) 8.x 或 9.x 上安装 SQL Server 2022 (16.x)。然后可以使用 sqlcmd 进行连接,创建第一个数据库并运行查询。 注意:本教程需要用户输入和 Internet 连接。 …...
游戏如何应对云手机刷量问题
云手机的实现原理是依托公有云和 ARM 虚拟化技术,为用户在云端提供一个安卓实例,用户可以将手机上的应用上传至云端,再通过视频流的方式,远程实时控制云手机。 市面上常见的几款云手机 原本需要手机提供的计算、存储等能力都改由…...
QTableView使用QSortFilterProxyModel后行号错乱
在Qt中,当你使用QSortFilterProxyModel对QTableView进行排序或过滤后,点击事件可能会返回一个不正确的行号,因为代理模型可能会改变数据的显示顺序。为了获取点击数据的真实行号和内容,你可以使用mapToSource()函数,它…...
【Python】 报错Can‘t find model ‘en_core_web_md‘
出现这种错误表明Python环境中找不到名为en_core_web_md的模型。这通常发生在使用spaCy库进行自然语言处理时,因为spaCy依赖于预先训练好的模型来进行词性标注、依赖分析、命名实体识别等任务。如果没有安装该模型,尝试加载它时会导致错误。 解决办法&a…...
每天五分钟深度学习框架pytorch:pytorch中已经定义好的损失函数
本文重点 前面我们学习了pytorch中两种模式的损失函数,一种是nn,另外一种是functional,本文将讲解pytorch中已经封装好的损失函数。其实nn的方式就是类,而functional的方式就是方法。nn中使用的也是functional。 损失函数中的参数 无论是nn还是functional,大多数的损失函…...
dedecms(四种webshell姿势)、aspcms webshell漏洞复现
一、aspcms webshell 1、登陆后台,在扩展功能的幻灯片设置模块,点击保存进行抓包查看 2、在slideTextStatus写入asp一句话木马 1%25><%25Eval(Request(chr(65)))%25><%25 密码是a,放行,修改成功 3、使用菜刀工具连…...
【STM32系统】基于STM32设计的智能垃圾桶(语音、颜色识别、称重、光强、烟雾、人体识别、步进电机、水泵)——文末资料下载
基于STM32设计的智能垃圾桶 演示视频: 基于STM32设计的智能垃圾桶 功能简介: 四个按键可分别打开四个垃圾桶(可回收垃圾、厨余垃圾、有害垃圾、其他垃圾) oled显示屏显示四个垃圾桶的打开/关闭状态、烟雾浓度、光照强度、称重的重量和识别到的颜色(白色、红色、绿色、蓝…...
GPT代码记录
#include <iostream>// 基类模板 template<typename T> class Base { public:void func() {std::cout << "Base function" << std::endl;} };// 特化的子类 template<typename T> class Derived : public Base<T> { public:void…...
【DeepSeek-R1代码相似度引擎解密】:3层语义比对机制、Token归一化偏差修正与Jaccard阈值黄金分割点
更多请点击: https://kaifayun.com 第一章:DeepSeek代码重复检测 DeepSeek-R1 模型在训练过程中引入了严格的代码去重机制,其核心目标是消除训练语料中语义等价或高度相似的代码片段,从而提升模型对真实编程模式的学习能力与泛化…...
物理引导的机器学习工作流:气候建模的融合创新与实践
1. 项目概述:当气候建模遇见机器学习如果你像我一样,在气候模拟这个领域摸爬滚打超过十年,就会深刻体会到一种“甜蜜的负担”:我们构建的地球系统模型(ESM)越来越精细,物理过程越来越复杂&#…...
信息系统项目管理师核心知识点精讲
一、项目整合管理(重点:项目章程与项目管理计划) 知识点详解: 项目整体管理是项目管理知识体系的核心,它确保项目各要素协调统一。在考试中,特别要掌握项目章程和项目管理计划的区别与联系。 项目章程是项目的“出生证明”,由项目发起人发布。它正式授权项目,赋予项…...
从Gamma函数到泊松分布:一个概率论中的含参量积分实用案例解析
Gamma函数与泊松分布:概率论中的数学之美 在数据科学和机器学习的实践中,概率分布构成了建模的基石。当我们深入探究这些分布背后的数学原理时,Gamma函数以其优雅的性质和广泛的应用脱颖而出。它不仅连接了离散与连续概率世界,更在…...
在Hermes Agent项目中接入Taotoken作为自定义模型供应商
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在Hermes Agent项目中接入Taotoken作为自定义模型供应商 基础教程类,针对使用Hermes Agent框架的开发者,详…...
C++ vector容器总结
vector基本概念功能:vector数据结构和数组非常相似,也称为单端数组vector与普通数组区别:不同之处在于数组是静态空间,而vector可以动态扩展动态扩展:并不是在原空间之后续接新空间,而是找更大的内存空间&a…...
Codex使用API Key授权无法使用插件?
小伙伴们,大家好,我是小溪,见字如面。对于没有ChatGPT账号的小伙伴来说,虽然可以通过API Key授权的方式使用Codex桌面端,但是会有一些限制。比如无法使用插件功能,无法使用Codex移动端进行远程控制等。为了…...
2026数据治理平台选型:五款产品如何赋能数据中台建设?
一、引言:数据中台的成败,关键在治理在数字化浪潮的席卷下,“数据中台”已成为当代企业信息化架构中的核心战略组件。然而,一个悖论正困扰着大量企业:数据中台的基础设施搭建日趋完善,但真正将数据转化为业…...
3个实用场景教你轻松解锁网易云音乐NCM加密文件:ncmdumpGUI完整指南
3个实用场景教你轻松解锁网易云音乐NCM加密文件:ncmdumpGUI完整指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经下载了网易云音乐的…...
Godot 4.2 + C# 避坑指南:手把手教你打包发布你的第一个2D游戏到Steam
Godot 4.2 C# 避坑指南:从开发到Steam发布的完整实战手册当你终于完成心爱的2D游戏开发,准备向全世界展示你的作品时,打包发布这个看似简单的环节往往会成为独立开发者最大的噩梦。特别是使用Godot 4.2搭配C#的项目,从导出设置到…...
