当前位置: 首页 > news >正文

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

   有两段代码是这样的:

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;//构造函数等省略@Overridepublic 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 对象。

相关文章:

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

有两段代码是这样的&#xff1a; A段&#xff1a; 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段&#xff1a; List<String> list1 new A…...

生成指定范围的随机整数

private static final Random RANDOM new Random();// 生成指定范围的随机整数public static int generateRandomInt(int min, int max) {return RANDOM.nextInt(max - min 1) min;}public static void main(String[] args) {Integer count 5;Integer randomInt generateR…...

少的缓存穿透是缓存击穿,大量的是缓存雪崩

只要请求穿过了缓存层&#xff0c;直接打到了数据库&#xff0c;我就把这个现象理解为缓存穿透。 只要缓存失效了&#xff0c;就会出现缓存穿透&#xff0c;然后根据失效缓存数量的多少&#xff0c;划分出缓存击穿和缓存雪崩 缓存一致性 先改redis再改mysql。...

设备能耗数据在线监测

在追求可持续发展和绿色经济的当下&#xff0c;企业对于设备能耗的管理愈发重视。设备能耗数据在线监测&#xff0c;不仅能帮助企业实时掌握设备的运行状况&#xff0c;还能为企业节能减排、降低运营成本提供有力支持。HiWoo Cloud平台凭借其先进的技术和丰富的经验&#xff0c…...

springboot整合websocket,超简单入门

springBoot整合webSocket&#xff0c;超简单入门 webSocket简洁 WebSocket 是一种基于 TCP 协议的全双工通信协议&#xff0c;它允许客户端和服务器之间建立持久的、双向的通信连接。相比传统的 HTTP 请求 - 响应模式&#xff0c;WebSocket 提供了实时、低延迟的数据传输能力。…...

代码随想录算法训练营第三十四天| 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

860.柠檬水找零 题目链接 思路 三种情况&#xff0c;一种贪心&#xff0c;在bill为20时&#xff0c;有一次贪心选择&#xff1a;优先考虑先找105&#xff0c;再考虑找3*5&#xff0c;因为5可以用于bill10和bill20两种情况 解题方法 第一种&#xff1a;bill5,直接收 第二种…...

ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2

ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2 1、 for i in range(3):Dev.step(3)Dev.turnRight()Dev.step(4)Dev.turnLeft()2、 for i in range(3):Spaceship.step(3)Spaceship.turnRight()Spaceship.step(1)3、 Dev.turnLeft() Dev.step(Dev.x - Item[1].…...

12.轻量级锁原理及其实战

文章目录 轻量级锁原理及其实战1.轻量级锁的核心原理2.轻量级锁的演示2.1.轻量级锁的演示代码2.2.结果分析 3.轻量级锁的分类3.1.普通自旋锁3.2.自适应自旋锁 4.轻量级锁的膨胀 轻量级锁原理及其实战 引入轻量级锁的主要目的是在多线程环境竞争不激烈的情况下&#xff0c; 通过…...

栈结构(c语言)

1.栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&am…...

【C++】C/C++中新const用法:const成员

欢迎来到CILMY23的博客 本篇主题为&#xff1a; C/C中新const用法&#xff1a;const成员 个人主页&#xff1a;CILMY23-CSDN博客 系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Linux 感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞…...

武汉凯迪正大—钢管焊缝裂纹探伤仪

产品概述 武汉凯迪正大无损探伤仪是一种便携式工业无损探伤仪器&#xff0c; 能够快速便捷、无损伤、精确地进行工件内部多种缺陷&#xff08;裂纹、夹杂、气孔等&#xff09;的检测、定位、评估和诊断。既可以用于实验室&#xff0c;也可以用于工程现场。 设置简单&#xff0c…...

为什么 IP 地址通常以 192.168 开头?

在网络配置中&#xff0c;我们经常会遇到以 192.168 开头的 IP 地址&#xff0c;例如 192.168.0.1 或者 192.168.1.100。 这些地址通常用于局域网中&#xff0c;但为什么要选择以 192.168 开头呢&#xff1f; 本文将深入探讨这个问题&#xff0c;并解释其背后的原因和历史渊源…...

elementUi中的el-table合计行添加点击事件

elementUi 文档中&#xff0c;合计行并没有点击事件&#xff0c;这里自己实现了合计行的点击事件。 created() {this.propertyList [{ property: order, label: 序号 },{ property: deptName, label: 单位名称 },{ property: contentPublishQuantity, label: 文章数量 },{ pro…...

Zookeeper集群搭建的一些问题

问题描述一&#xff1a; Cannot open channel to 2 at election address /192.168.60.132:3888解决方案&#xff1a; 查看zookeeper配置文件zoo.cfg / zoo_sample.cfg中集群配置部分 server.1zoo1-net1:2888:3888|zoo1-net2:2889:3889 server.2zoo2-net1:2888:3888|zoo2-net2…...

【线性代数】俗说矩阵听课笔记

基础解系的概念 线性方程组的解 21行列式和矩阵秩Rank的等价刻画 子式 标准型 利用子式求解矩阵的rank 24零积秩不等式 齐次线性方程组的基础解系 rank的两个重要结论 &#xffe5;25伴随矩阵的rank 奇异矩阵&#xff1a;行列式0的矩阵 31线性相关&#xff0c;线性无关&#…...

物联网技术在数字化工厂中的应用,你知道多少?——青创智通

工业物联网解决方案-工业IOT-青创智通 物联网&#xff08;IoT&#xff09;技术在数字化工厂的应用正日益成为工业革命的重要推动力。随着科技的飞速发展&#xff0c;物联网技术不断革新&#xff0c;其在数字化工厂中的应用也呈现出愈发广泛和深入的态势。本文将详细探讨物联网…...

nacos开启登录开关启动报错“Unable to start embedded Tomcat”

nacos 版本&#xff1a;2.3.2 2.2.2版本之前的Nacos默认控制台&#xff0c;无论服务端是否开启鉴权&#xff0c;都会存在一个登录页&#xff1b;在之后的版本关闭了默认登录页面&#xff0c;无需登录直接进入控制台操作。在这里我们可以在官网可以看到相关介绍 而我现在所用的…...

Linux|了解如何使用 awk 内置变量

引言 当我们揭开 Awk 功能部分时&#xff0c;我们将介绍 Awk 中内置变量的概念。您可以在 Awk 中使用两种类型的变量&#xff1a;用户定义的变量和内置变量。 内置变量的值已经在 Awk 中定义&#xff0c;但我们也可以仔细更改这些值&#xff0c;内置变量包括&#xff1a; FILEN…...

代码随想录-算法训练营day29【回溯算法05:递增子序列、全排列】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第七章 回溯算法part05* 491.递增子序列 * 46.全排列 * 47.全排列 II详细布置 491.递增子序列 本题和大家刚做过的 90.子集II 非常像&#xff0c;但又很不一样&#xff0c;很容易掉坑里。 https://programmercarl.com…...

704. 二分查找

Problem: 704. 二分查找 &#x1f437;我的leetcode主页 文章目录 题目分类思路什么是二分查找如何理解时间复杂度 解题方法Code 题目 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&a…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...