深拷贝|浅拷贝
目录
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…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...