javalist复制:浅拷贝与深拷贝

yizhihongxing

javalist复制:浅拷贝与深拷贝

在Java中,有时候我们需要复制一个List对象,这时候就需要考虑到复制的方式。一般来说,复制方式分为浅拷贝和深拷贝。

浅拷贝

浅拷贝是指将一个对象复制到一个新的对象中,但是这两个对象中的元素是共享的,即对一个对象进行修改会影响到另一个对象。在Java中,List的clone方法就是浅拷贝。

可以看下面的例子:

List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);

List<Integer> list2 = (ArrayList)list1.clone();

System.out.println("list1: " + list1);
System.out.println("list2: " + list2);

list2.add(4);

System.out.println("list1: " + list1);
System.out.println("list2: " + list2);

运行结果为:

list1: [1, 2, 3]
list2: [1, 2, 3]
list1: [1, 2, 3, 4]
list2: [1, 2, 3, 4]

我们可以看到,list2添加了一个元素4,但是list1也跟着改变了。这就是浅拷贝的特点。

深拷贝

深拷贝是指将原始对象完全复制一份,即复制后的对象和原始对象没有任何关系。在Java中,我们可以通过序列化和反序列化来实现深拷贝。

可以看下面的例子:

List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);

List<Integer> list2 = new ArrayList<>();

try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos1 = new ObjectOutputStream(baos);
    oos1.writeObject(list1);

    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bais);
    list2 = (ArrayList<Integer>) ois.readObject();
} catch (Exception e) {
    e.printStackTrace();
}

System.out.println("list1: " + list1);
System.out.println("list2: " + list2);

list2.add(4);

System.out.println("list1: " + list1);
System.out.println("list2: " + list2);

运行结果为:

list1: [1, 2, 3]
list2: [1, 2, 3]
list1: [1, 2, 3]
list2: [1, 2, 3, 4]

我们可以看到,list2添加一个元素4,但是list1没有变化,这就是深拷贝的特点。

小结

在实际开发中,我们需要根据实际情况来选择使用哪种方式进行复制。如果我们需要两个对象的元素共享,那么使用浅拷贝;如果我们需要复制后的对象和原始对象没有任何关系,那么使用深拷贝。由于List的clone方法是浅拷贝,如果我们需要进行深拷贝,我们可以使用序列化和反序列化。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javalist复制:浅拷贝与深拷贝 - Python技术站

(0)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • uniappui框架——uview

    UniApp UI框架——uView uView是一个基于Vue.js的UniApp UI框架,提供了丰富的组件和工具,可以帮助开发者快速构建高质量的UniApp应用。本攻略将介绍uView的基本用法和示例。 安装 在使用uView之前,需要先安装它。以下是一个示例,展示了如何使用npm安装uView: npm install uview-ui 引入 在安装…

    other 2023年5月9日
    00
  • js onload处理html页面加载之后的事件

    介绍 JS Onload 处理 HTML 页面加载之后的事件,需要分以下几个方面进行说明: Javascript onload事件的概念和基本语法 如何使用Javascript的onload事件 JS onload事件的应用场景 1. Javascript onload事件的概念和基本语法 JS Onload 是Javascript的事件之一。它的含义是:当…

    other 2023年6月25日
    00
  • AngularJs学习第五篇从Controller控制器谈谈$scope作用域

    AngularJS学习第五篇:从Controller控制器谈谈$scope作用域 在AngularJS中,控制器(Controller)是连接视图(View)和模型(Model)的重要组件之一。控制器通过$scope对象来管理视图和模型之间的数据交互。本篇攻略将详细讲解$scope作用域的使用方法和示例。 $scope作用域的基本概念 $scope是Angu…

    other 2023年8月20日
    00
  • 浅析Python面向对象编程

    浅析Python面向对象编程 什么是面向对象编程 面向对象编程(Object Oriented Programming, OOP) 是一种程序设计的思想方式,是以对象为基础来构建程序的编程范式。 在面向对象编程中,一切程序实体都是对象,对象之间通过消息传递进行交互。每个对象都是一个可以执行任务、处理数据的独立体,由一个或多个方法构成。方法是属于对象的,只有该…

    other 2023年6月27日
    00
  • cnpm不是内部命令的解决方案:配置环境变量【推荐】

    下面是“cnpm不是内部命令”的解决方案:配置环境变量。 问题描述 在使用npm安装依赖包时,有时候会出现像下面这样的提示: ‘cnpm’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 这是因为cnpm并不是npm自带的命令,而是需要额外进行安装的。而如果我们每次都需要在命令行中使用npm install -g cnpm来安装cnpm,则使用起来非…

    other 2023年6月26日
    00
  • React路由参数传递与嵌套路由的实现详细讲解

    React 路由参数传递与嵌套路由的实现详细讲解 React 路由参数传递和嵌套路由是在构建 React 应用时非常常见的需求。本攻略将详细讲解如何实现这两个功能,并提供两个示例说明。 路由参数传递 在 React 中,我们可以使用路由参数来传递数据给组件。以下是实现路由参数传递的步骤: 安装 React 路由库:首先,确保你已经安装了 React 路由库。…

    other 2023年7月28日
    00
  • java实现双向链表的增删改

    Java语言中实现双向链表的增删改可以通过以下步骤进行。 一、创建双向链表节点类 首先,需要创建一个双向链表节点类,该类包含节点值以及指向前驱节点和后继节点的指针。以下是该类的代码实现。 public class DoublyListNode { public int val; public DoublyListNode prev; public Doubl…

    other 2023年6月27日
    00
  • 网站制作不可不知的URL知识

    网站制作不可不知的URL知识攻略 在网站制作过程中,URL(统一资源定位符)是非常重要的一部分。它不仅是用户访问网站的入口,还对搜索引擎优化(SEO)和用户体验起着重要作用。下面是一份详细的URL知识攻略,帮助你了解网站制作中不可不知的URL知识。 1. URL的基本结构 URL由多个部分组成,包括协议、域名、路径和查询参数等。以下是URL的基本结构: 协议…

    other 2023年8月5日
    00
合作推广
合作推广
分享本页
返回顶部