【java】java ArrayList的深拷贝与浅拷贝

2023-11-07

一、前言:

ArrayList是我们经常会用到的集合类,有时候我们为了要不改变原来的数据需要重新拷贝一个新的ArrayList,今天在使用ArrayList拷贝时遇到了一些问题,这里整理并记录一下。

二、准备:

首先: ArrayList的常见的拷贝方法有很多,其中都是浅拷贝,这里介绍几种浅拷贝的方式:

  1. 通过构造函数方法拷贝:
List<Integer> newList = new ArrayList<>(list);
  1. addAll()方法
List<Integer> newList = new ArrayList<>();
newList.addAll(list);
  1. Collections.copy方法
List<Integer> newList = new ArrayList<>();
newList.addAll(list);
Collections.copy(newList, list)
  1. stream 方法

java 8 的新特性

List<Integer> newList = list.stream().collect(toList());

另外一点
clone()方式有些特殊,最开始我以为通过clone()是实现深拷贝。但其实clone()也是浅拷贝,原因如下:
在这里插入图片描述
因为通常我们使用的类型是Interger或者String类型的List,Interger和String类型都是不可变类,那么只需要通过浅拷贝拷贝一层即可。给人的感觉是完全重新生成了一个新的ArrayList。

但是如果我们将类型改成我们自己的类型时,就会出问题。

三、测试

将类型改成对象,在试一下:

// 模拟些数据
Shard shard1 = new Shard(1,"张三","node1");
Shard shard2 = new Shard(2,"李四","node2");
Shard shard3 = new Shard(3,"王五","node3");

List<Shard> list = Arrays.asList(shard1, shard2, shard3);

// 拷贝一个新的list
List<Shard> newList = new ArrayList<>();
newList.addAll(list);
Collections.copy(newList, list);

// 修改新的list里数据
newList.forEach(e -> e.setShardNum(4));

// 遍历旧的list
list.forEach(e -> System.out.println(e.getShardNum()));

结果:

4
4
4

可以看出这样的List拷贝都是浅拷贝,都是拷贝的对象的引用,并没有真正的去深拷贝。大家可以试试别的方法,应该都是不行的。

四、深拷贝

那么如何实现一个深拷贝,网上的推荐是使用序列化方法可以实现深拷贝。

代码逻辑贴下:

public class CloneUtil {
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T obj){
        T cloneObj = null;
        //写入字节流
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream obs = new ObjectOutputStream(out);
            obs.writeObject(obj);
            obs.close();

            //分配内存,写入原始对象,生成新对象
            ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(ios);
            //返回生成的新对象
            cloneObj = (T) ois.readObject();
            ois.close();
        }catch(IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return cloneObj;
    }
}

使用:

for(Shard shard: list) {
  Shard newShard = CloneUtil.clone(shard);
    newList.add(newShard);
}

注意点:所有需要拷贝到的对象,通通要实现Serializable

在这里插入图片描述

参考

https://www.cnblogs.com/liusandao/p/12345208.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【java】java ArrayList的深拷贝与浅拷贝 的相关文章

  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • Spark 1.3.1 上的 Apache Phoenix(4.3.1 和 4.4.0-HBase-0.98)ClassNotFoundException

    我正在尝试通过 Spark 连接到 Phoenix 并且在通过 JDBC 驱动程序打开连接时不断收到以下异常 为简洁起见 下面是完整的堆栈跟踪 Caused by java lang ClassNotFoundException org a
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 使用Caliper时如何指定命令行?

    我发现 Google 的微型基准测试项目 Caliper 非常有趣 但文档仍然 除了一些示例 完全不存在 我有两种不同的情况 需要影响 JVM Caliper 启动的命令行 我需要设置一些固定 最好在几个固定值之间交替 D 参数 我需要指定
  • 在 Mac 上正确运行基于 SWT 的跨平台 jar

    我一直致力于一个基于 SWT 的项目 该项目旨在部署为 Java Web Start 从而可以在多个平台上使用 到目前为止 我已经成功解决了由于 SWT 依赖的系统特定库而出现的导出问题 请参阅相关thread https stackove
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • 官网解读-fastcgi_param

    Syntax fastcgi param parameter value if not empty Default Context http server location Sets a parameter that should be p
  • iOS中的数据持久化方式

    iOS中的数据持久化方式 基本上有以下四种 属性列表 对象归档 SQLite3和Core Data 1 属性列表 涉及到的主要类 NSUserDefaults 一般 NSUserDefaults standardUserDefaults 就
  • 教程--从零开始使用BiSeNet(语义分割)网络训练自己的数据集

    引言 为了从图片分割出我们想要的特征 我们采用BiSeNet作为分割模型 并且在自己制作的数据集上进行训练测试 注 训练是在linux环境下的 Win下训练可能会有点问题 一 下载BiSeNet网络的安装包 1 下载地址 GitHub Co
  • matlab 非均匀体素下采样

    目录 一 非均匀下采样 二 代码实现 三 结果展示 1 原始点云 2 采样结果 四 参考链接 一 非均匀下采样 ptCloudOut pcdownsample ptCloudIn nonuniformGridSample maxNumPoi
  • java线程池(四):ForkJoinPool的使用及基本原理

    文章目录 1 ForkJoinPool是什么 1 1 分治法 1 2 工作窃取 work stealing 2 简单使用 2 1 不带返回值的计算 2 2 带返回值的计算 3 ForkJoin源码注释 3 1 类注释 3 2 关于原理的注释
  • 软件测试用例有五十个以上的,软件测试大牛都是这样写测试用例的,你get到了嘛?...

    1 用于语句覆盖的基路径法 基路径法保证设计出的测试用例 使程序的每一个可执行语句至少执行一次 即实现语句覆盖 基路径法是理论与应用脱节的典型 基本上没有应用价值 读者稍作了解即可 不必理解和掌握 基路径法步骤如下 1 画出程序的控制流图
  • C语言函数函数(斐波那契函数)

    作者 几冬雪来 时间 2023年2月2日 内容 C语言函数函数讲解之斐波那契函数篇 目录 前言 斐波那契函数 1 什么是斐波那契函数 2 斐波那契函数怎么实现 3 如何用C语言书写斐波那契函数 4 什么时候使用递归 什么时候使用非递归 结尾
  • uniapp开发微信小程序通过文件流下载文件

    uni downloadFile url xx 请求地址 header token token token 获取 success res gt if res statusCode 200 var filePath res tempFileP
  • 谈一下为什么程序员不要进外包吧

    从2016年毕业到现在入行也有4年多 待过几家公司 外包和非外包都待过 个人感觉 外包和非外包的区别在于后期维护和迭代升级这个阶段上 一般外包都是开发通过验收或者根本就没有通过验收当你把项目推动到某一个阶段之后你就要进入下一个项目组 这样让
  • 什么是编译?

    编译 compilation compile 1 利用编译程序从源语言编写的源程序产生目标程序的过程 2 用编译程序产生目标程序的动作 编译就是把高级语言变成计算机可以识别的2进制语言 计算机只认识1和0 编译程序把人们熟悉的语言换成2进制
  • lambda表达式java项目常用_LAMBDA表达式常用 (全)

    1 select语句 books Select p gt new p Title p UnitPrice p Author 需用匿名方式 2 where语句 books Where p gt p UnitPrice 100 p Title
  • 从七个方面,面试BAT大厂高级工程师,纯干货!

    转载注明 https blog csdn net WantFlyDaCheng article details 100078782 一 框架是重点 但别让人感觉你只会山寨别人的代码 二 别单纯看单机版的框架 适当了解些分布式 三 数据库方面
  • 安装 WebStorm 后的一些基本配置

    前言 在安装完 WebStorm 后我们需要配置一些东西来加快我们的开发效率 下面给大家列出一些基本的配置 1 设置 WebStorm 标签下的默认缩进 问题 在 WebStorm 的 html 文件中 默认在标签下的子标签是没有进行缩进处
  • 深入理解JVM(四)-执行引擎

    本文章是根据 深入理解Java虚拟机 一书 并参考网上其他文档进行的系统性的和简单容易理解的方式进行的整理 一 执行引擎 执行引擎是Java最核心的组成部分之一 具有执行代码的能力 如下图所示 1 运行时栈帧结构 栈帧是用于支持虚拟机进行方
  • mysql版本号怎么看_查看Mysql版本号的五种不同方法介绍

    查看mysql数据库版本 可以使用命令行模式进入mysql会看到最开始的提示符 也可以在命令行中使用status查看 又可以使用系统函数等 以下是查看mysql版本信息的详细介绍 1 使用命令行模式进入mysql会看到最开始的提示符 You
  • 巧妙利用kickstart实现自动化安装全get

    本文转载链接 https blog csdn net Nanjing bokebi article details 103035331 运用kickstart服务创建应答文件 实现自动化运维 运维自动化发展历程及技术应用 理解kicksta
  • 用Qt写一个简单的音乐播放器(二):增加界面(开始和暂停音乐)

    一 前言 在用Qt写一个简单的音乐播放器 一 使用QMediaPlayer播放音乐中 我们已经知道如何去使用QMediaPlayer播放音乐 但是一个对于一个音乐播放器来说 这是远远不够的 至少我们需要有一个简单的用户操作界面吧 让用户开业
  • 华为2019数字芯片岗笔试解析二(多选部分)

    首发来自微信公众号 数字芯片设计 1 异步设计的特点是 A 没有时钟skew问题 B 可移植性高 C 低电源消耗 D 设计可靠性高 解析 同步电路设计利用时钟脉冲使其子系统同步运作 而异步电路设计不使用时钟脉冲做同步 其子系统是使用特殊的
  • ucos2-cpu_c.c-位带操作

    在uC CPU ARM Cortex M3 cpu c c中有两个位带访问的函数 使用位带访问技术来对内存或外设地址addr中的第bit nbr位进行清零操作 void CPU BitBandClr CPU ADDR addr CPU IN
  • 【java】java ArrayList的深拷贝与浅拷贝

    一 前言 ArrayList是我们经常会用到的集合类 有时候我们为了要不改变原来的数据需要重新拷贝一个新的ArrayList 今天在使用ArrayList拷贝时遇到了一些问题 这里整理并记录一下 二 准备 首先 ArrayList的常见的拷