深拷贝、浅拷贝

一、概念

1、概念

在Java中,对象的拷贝分为深拷贝和浅拷贝,这两个概念描述了对象拷贝的方式和效果。

浅拷贝(Shallow Copy):
浅拷贝是指在拷贝对象时,仅复制对象本身和其内部的基本数据类型字段,而不会复制引用类型字段所引用的对象。这意味着新对象和原始对象会共享同一个引用对象,修改其中一个对象的引用字段会影响到另一个对象。简单来说,浅拷贝只是创建了一个指向原始对象的新对象的引用。

深拷贝(Deep Copy):
深拷贝是指在拷贝对象时,不仅复制对象本身和其内部的基本数据类型字段,还会递归复制引用类型字段所引用的对象。这样,新对象和原始对象将完全独立,对任何一个对象的修改都不会影响到另一个对象。简而言之,深拷贝会创建一个全新的对象及其所有关联的对象。

实现深拷贝的方式可以是通过实现Cloneable接口并重写clone()方法,或者使用序列化和反序列化等方法来复制对象及其引用的对象。需要根据具体的需求选择适合的方式进行深拷贝操作。

需要注意的是,浅拷贝和深拷贝的概念适用于对象的拷贝操作,而不同于对象的赋值操作。在赋值操作中,无论是基本数据类型还是引用类型,都只是将一个对象的引用赋值给了另一个对象,它们仍然指向同一个对象,修改其中一个对象会影响到另一个对象。

2、对比

简单地址值复制

内容完全一致,只是由2个变量值,进行取值使用(user01user02)。

User user01 = new User();
User user02 = user01;

覆盖子集的地址值的复制

借助一定的API,表明子集的类型。能够实现对子集地址值(obj02)的覆盖。当子集中obj02数据变更,则复制后值也变更。

在这里插入图片描述

完全的深拷贝

目前只能借助格式化来实现,可以采用流进行复制,也可以借助JSON格式化来实现。

3、常用API整理

在这里插入图片描述

二、浅拷贝

1、实体类

核心API

import org.springframework.beans.BeanUtils;
BeanUtils.copyProperties(user01, user02);

代码:

User user01 = new User("张三", 18, "北京");
User user02 = new User();

BeanUtils.copyProperties(user01, user02);
System.out.println(user01.equals(user02));
System.out.println(user01);
System.out.println(user02);

System.out.println("====更新值====");
user01.setName("王五");
System.out.println(user01);
System.out.println(user02);

结果:

true
User(name=张三, age=18, address=北京)
User(name=张三, age=18, address=北京)
====更新值====
User(name=王五, age=18, address=北京)
User(name=张三, age=18, address=北京)

2、Map类型

核心API

HashMap<String, String> newMap01 = new HashMap<>(hashMap);

newMap02.putAll(hashMap);

代码:

HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("key01", "value01");
hashMap.put("key02", "value02");
hashMap.put("key03", "value03");
//  浅拷贝
HashMap<String, String> newMap01 = new HashMap<>(hashMap);
HashMap<String, String> newMap02 = new HashMap<>();
newMap02.putAll(hashMap);
System.out.println(hashMap);
System.out.println(newMap01);
System.out.println(newMap02);

结果:

{key03=value03, key02=value02, key01=value01}
{key03=value03, key02=value02, key01=value01}
{key03=value03, key02=value02, key01=value01}
{level02={key01=value01}}
{level02={key01=value01}}

反例(不支持深拷贝):

//  反例
HashMap<String, Map> level01 = new HashMap<>();
HashMap<String, String> level02 = new HashMap<>();
level02.put("key01", "value01");
level01.put("level02", level02);
HashMap<String, Map> newLevel = new HashMap<>(level01);
System.out.println(level01);
System.out.println(newLevel);
System.out.println("更新值后");
level02.put("key01", "======");
System.out.println(level01);
System.out.println(newLevel);
{level02={key01=value01}}
{level02={key01=======}}

3、数组

核心API

int[] arr2 = Arrays.copyOf(arr1, arr1.length);
// 复制数组解析: (原数组,从原数组的起始位置,目标数组,目标数组的起始位置,要复制的数组长度)
System.arraycopy(arr1, 0, arr3, 0, arr1.length);

代码:

int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = Arrays.copyOf(arr1, arr1.length);
int[] arr3 = new int[arr1.length];
// 复制数组解析: (原数组,从原数组的起始位置,目标数组,目标数组的起始位置,要复制的数组长度)
System.arraycopy(arr1, 0, arr3, 0, arr1.length);
System.out.println(JSON.toJSONString(arr1));
System.out.println(JSON.toJSONString(arr2));
System.out.println(JSON.toJSONString(arr3));

结果:

[1,2,3,4,5]
[1,2,3,4,5]
[1,2,3,4,5]

4、集合

核心API

//	复制对象值的拷贝
import cn.hutool.core.bean.BeanUtil;
List<User> arrayLists = BeanUtil.copyToList(users, User.class);

浅拷贝:
users03.addAll(users);

ArrayList<User> users04 = new ArrayList<>(users);

代码:

User user03 = new User("张三", 18, "北京");
User user04 = new User("李四", 19, "天津");
ArrayList<User> users = new ArrayList<>();
users.add(user03);
users.add(user04);
List<User> arrayLists = BeanUtil.copyToList(users, User.c
ArrayList<User> users03 = new ArrayList<>();
users03.addAll(users);
ArrayList<User> users04 = new ArrayList<>(users);
                                            
//	打印初始值
System.out.println(JSON.toJSONString(users));
System.out.println(JSON.toJSONString(arrayLists));
System.out.println(JSON.toJSONString(users03));
System.out.println(JSON.toJSONString(users04));
System.out.println("====");
//    更新某个对象值
user03.setName("ddddd");
System.out.println(JSON.toJSONString(users));
System.out.println(JSON.toJSONString(arrayLists));
System.out.println(JSON.toJSONString(users03));
System.out.println(JSON.toJSONString(users04));

结果:

[{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}]
[{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}]
[{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}]
[{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}]
====
[{"address":"北京","age":18,"name":"ddddd"},{"address":"天津","age":19,"name":"李四"}]
[{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}]
[{"address":"北京","age":18,"name":"ddddd"},{"address":"天津","age":19,"name":"李四"}]
[{"address":"北京","age":18,"name":"ddddd"},{"address":"天津","age":19,"name":"李四"}]

5、JSONObject

在这里插入图片描述

核心API

obj02.putAll(obj01);

代码:

JSONObject one = new JSONObject();
one.put("one", "fish");
JSONObject two = new JSONObject();
two.putAll(one);

//	打印初始值
System.out.println("init: one: " + one.toString());
System.out.println("init: two: " + two.toString());
//	更改值
one.put("one", "fish=======");
System.out.println("init: one: " + one.toString());
System.out.println("init: two: " + two.toString());

2层子对象

JSONObject obj01 = new JSONObject();
JSONObject obj01_01 = new JSONObject();
obj01.put("dd111", obj01_01);
obj01_01.put("key01", "value01");
JSONObject obj02 = new JSONObject();
obj02.putAll(obj01);
//	打印初始值
System.out.println(obj01);
System.out.println(obj02);
//	更改值
obj01_01.put("dd111", "value01=============");
System.out.println(obj01);
System.out.println(obj02);

结果:

init: one: {"one":"fish"}
init: two: {"one":"fish"}
init: one: {"one":"fish======="}
init: two: {"one":"fish"}
============================================================
{"dd111":{"key01":"value01"}}
{"dd111":{"key01":"value01"}}
{"dd111":{"key01":"value01","dd111":"value01============="}}
{"dd111":{"key01":"value01","dd111":"value01============="}}

6、JsonArray

核心API

JSONArray jsonArray02 = (JSONArray) jsonArray01.clone();

jsonArray03.addAll(jsonArray01);

代码:

JSONArray jsonArray01 = new JSONArray();
jsonArray01.add("test01");
jsonArray01.add("test02");
jsonArray01.add("test03");
JSONArray jsonArray02 = (JSONArray) jsonArray01.clone();
JSONArray jsonArray03 = new JSONArray();
jsonArray03.addAll(jsonArray01);
//	打印初始值
System.out.println(jsonArray01);
System.out.println(jsonArray02);
System.out.println(jsonArray03);

子集值,更新

JSONArray jsonArray01 = new JSONArray();
jsonArray01.add("test01");
jsonArray01.add("test02");
jsonArray01.add("test03");
JSONObject one = new JSONObject();
one.put("one", "fish");
jsonArray01.add(one);
JSONArray jsonArray05 = (JSONArray) jsonArray01.clone()
JSONArray jsonArray06 = new JSONArray();
jsonArray06.addAll(jsonArray01);

//	打印初始值
System.out.println(jsonArray01);
System.out.println(jsonArray05);
System.out.println(jsonArray06);
//	值更新
one.put("two", "two");
System.out.println(jsonArray01);
System.out.println(jsonArray05);
System.out.println(jsonArray06);

结果:

["test01","test02","test03"]
["test01","test02","test03"]
["test01","test02","test03"]
---

["test01","test02","test03",{"one":"fish"}]
["test01","test02","test03",{"one":"fish"}]
["test01","test02","test03",{"one":"fish"}]
["test01","test02","test03",{"one":"fish","two":"two"}]
["test01","test02","test03",{"one":"fish","two":"two"}]
["test01","test02","test03",{"one":"fish","two":"two"}]

三、深拷贝

实体类

User user = new User();
String s = JSON.toJSONString(user);
User userClone = JSON.parseObject(s, User.class);

Map

HashMap<String, String> hashMap = new HashMap<>();
String s1 = JSON.toJSONString(hashMap);
HashMap hashMap1 = JSON.parseObject(s, HashMap.class);

List集合

ArrayList<User> users = new ArrayList<>();
String s2 = JSON.toJSONString(users);
ArrayList arrayList = JSON.parseObject(s2, ArrayList.class);

JSONObject

JSONObject jsonObject = new JSONObject();
String s3 = jsonObject.toJSONString();
JSONObject jsonObject1 = JSON.parseObject(s3, JSONObject.class);

JSONArray

JSONArray jsonArray = new JSONArray();
String s4 = jsonArray.toJSONString();
JSONArray jsonArray1 = JSON.parseObject(s4, JSONArray.class);

四、XMind文件

CSDN

https://download.csdn.net/download/weixin_44624117/87778427

在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
包装类的深拷贝浅拷贝是指在复制一个包装类对象时,对于其中的字段如何进行复制的过程。 浅拷贝是指只复制值类型字段的值,而对于引用类型字段,只复制其引用。也就是说,新创建的对象和原始对象会共享一部分内存空间,导致对其中一个对象进行修改会影响到另一个对象。 深拷贝是指除了复制值类型字段的值外,还会对引用类型字段所指向的对象进行一次完全的拷贝。也就是说,新创建的对象会有自己独立的一份内存空间,对其中一个对象进行修改不会影响到另一个对象。 实现深拷贝的方法有多种。其中一种常用的方法是利用反序列化技术,通过将对象序列化为字节流,然后再将字节流反序列化为一个全新的对象。这种方法可以解决多层套娃式的深拷贝问题,并且效果非常好。 另外一种实现深拷贝的方式是通过覆写对象的clone()方法,实现引用对象的深度遍历式拷贝。这种方式需要对clone()方法进行重写,以便对引用对象进行递归拷贝。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【Java深拷贝浅拷贝Java实现)](https://blog.csdn.net/hhb442/article/details/128801265)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ha_lydms

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值