java ArrayList的深拷贝与浅拷贝问题

yizhihongxing

什么是深拷贝和浅拷贝?

在Java中,我们经常使用集合类来存储和操作对象。其中ArrayList是一种常用的动态数组(可变长度的数组)实现。但是在使用过程中,会遇到对象拷贝的问题:是深拷贝还是浅拷贝?

深拷贝和浅拷贝是针对对象进行复制、克隆的概念,假设有一个对象A,它有一个成员变量B,而B又有一个成员变量C,那么进行拷贝时,如果只是将A拷贝一份,那么B与其指向的C仍是原来A中的对象。此时,拷贝出来的对象与原对象虽然有相同的属性值,但却是两个相互独立的对象。这就是深拷贝。而只拷贝A对象,而B和C仍然是原对象A所指向的对象,则被称为浅拷贝。

ArrayList的浅拷贝和深拷贝

当我们进行ArrayList的拷贝时,Java提供两种方法:

  1. Object.clone()方法
  2. 通过循环新建对象复制所有元素

第一种方法是浅拷贝,由于ArrayList中的元素通常是对象引用,clone()方法只会复制对象的引用而不是对象本身,因此,如果我们对ArrayList中的元素进行修改操作,原列表和新列表中引用的同一个对象的内容都会改变。因此在我们使用ArrayList时,对于含有对象引用的数据结构,在使用clone()方法时应当特别小心。

下面我们通过两个示例来演示ArrayList的浅拷贝和深拷贝

示例一:浅拷贝

public class ShallowCopy {

    public static void main(String[] args) {
        //创建一个原始对象ArrayList
        ArrayList<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        //进行对象的浅拷贝
        ArrayList<String> clonedList = (ArrayList<String>)originalList.clone();

        //修改拷贝后的对象
        clonedList.set(1, "Watermelon");

        //输出结果
        System.out.println("Original ArrayList: " + originalList);
        System.out.println("Cloned ArrayList: " + clonedList);
    }
}

输出结果:

Original ArrayList: [Apple, Banana, Cherry]
Cloned ArrayList: [Apple, Watermelon, Cherry]

可以发现,尽管我们只是修改了拷贝后的对象,但原始对象的内容也随之改变了。

示例二:深拷贝

class Person implements Cloneable {
    String name;
    int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "[name=" + name + ", age=" + age + "]";
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class DeepCopy {

    public static void main(String[] args) throws CloneNotSupportedException {
        //创建一个原始对象ArrayList
        ArrayList<Person> originalList = new ArrayList<>();
        originalList.add(new Person("Tom", 20));
        originalList.add(new Person("Jack", 21));
        originalList.add(new Person("Jerry", 22));

        //进行对象的深拷贝
        ArrayList<Person> clonedList = new ArrayList<>();
        for (Person person : originalList) {
           clonedList.add((Person)person.clone());
        }

        //修改拷贝后的对象
        clonedList.get(1).age = 25;

        //输出结果
        System.out.println("Original ArrayList: " + originalList);
        System.out.println("Cloned ArrayList: " + clonedList);
    }
}

输出结果:

Original ArrayList: [[name=Tom, age=20], [name=Jack, age=21], [name=Jerry, age=22]]
Cloned ArrayList: [[name=Tom, age=20], [name=Jack, age=25], [name=Jerry, age=22]]

可以发现,尽管我们只是修改了拷贝后的对象,但原始对象的内容没有发生变化。这证明我们成功进行了深拷贝。

总之,当我们需要对包含对象引用的数据结构进行拷贝时,应该根据实际需要选择浅拷贝还是深拷贝。

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

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • Win10更新四月正式版17134.166累积更新补丁 附更新内容和下载地址

    Win10更新四月正式版17134.166累积更新补丁攻略 本攻略将详细讲解Win10更新四月正式版17134.166累积更新补丁的安装过程,并提供更新内容和下载地址。请按照以下步骤进行操作: 步骤一:检查系统版本 首先,确保你的系统版本是Win10更新四月正式版17134.166。你可以通过以下步骤检查: 打开“设置”应用程序。 点击“系统”。 在左侧导航…

    other 2023年8月4日
    00
  • python3中eval函数用法使用简介

    当然!下面是关于\”Python3中eval函数用法使用简介\”的完整攻略,包含两个示例说明。 … … … … … … … … … … … … … … … … … … … … … … …

    other 2023年8月20日
    00
  • ADO.Net 类型化DataSet的简单介绍

    ADO.Net 类型化 DataSet的简单介绍 什么是类型化 DataSet? 类型化 DataSet 是 ADO.Net 框架中的一种数据访问技术,它提供了一种强类型的方式来与关系型数据库进行交互和操作。通过使用类型化 DataSet,我们可以在编译时对数据进行验证,并且能够以面向对象的方式进行数据的访问和操作,从而提供更为可靠和灵活的数据访问。 如何创…

    other 2023年6月28日
    00
  • 微软为Windows开发中心增加新功能:改进应用提交流程、下载图标徽章等

    微软为Windows开发中心增加新功能 微软为Windows开发者增加了一些新功能,改善了应用提交流程,以及增加了新的下载图标徽章等方面的更新。在Windows开发中心上,开发者可以使用这些新功能来更好地管理和推销他们的应用程序。 改进应用提交流程 微软在Windows开发中心中改进了应用提交流程。这使得开发者能够更快地提交应用,并获得更多的反馈和指导。 在…

    other 2023年6月26日
    00
  • 3D渲染管线

    3D渲染管线的完整攻略 本文将为您提供3D渲染管线的完整攻略,包括渲染管线的概念、渲染管线的阶段、渲染管线的优化和两个示例说明。 渲染管线的概念 3D渲染管线是指将3D场景中的几何图形转换为2D图像的过程。渲染管线通常由多个阶段组成,每个阶段都有特定的功能。渲染管线的目的是将3D场景中的几何图形转换为2D图像,以便在屏幕上显示。 渲染管线的阶段 以下是渲染管…

    other 2023年5月6日
    00
  • 积累linux常用命令大全

    下面我来详细讲解关于“积累Linux常用命令大全”的完整攻略。 1. 收集常用命令 首先,我们需要收集常用的命令。可以通过以下途径收集: 通过搜索引擎搜索“linux 常用命令”,找到一些常用命令的列表。比如 https://www.cnblogs.com/peida/archive/2012/12/05/2807227.html 把自己平时常用的命令整理出…

    other 2023年6月26日
    00
  • XP系统提示Baidusdsvc.exe应用程序错误的故障原因分析及解决方法

    XP系统提示Baidusdsvc.exe应用程序错误的故障原因分析及解决方法 问题现象描述 在XP系统中,当用户启动电脑或运行某个应用程序时,可能会收到如下错误提示信息: “应用程序错误, 应用程序名:baidusdsvc.exe, 出现应用程序错误,应用程序将被关闭,重启计算机再试一次” 问题原因分析 该错误通常是由以下原因导致: Baidu安全卫士等第三…

    other 2023年6月25日
    00
  • Python 设计模式中的创建型建造者模式

    Python 设计模式中的创建型建造者模式 创建型设计模式中的建造者模式(Builder Pattern)用于创建复杂对象,将对象的构建过程与其表示分离,以便相同的构建过程可以创建不同的表示。 1. 定义产品类 首先,我们需要定义一个产品类,该类包含需要构建的复杂对象的属性和方法。 class Product: def __init__(self): sel…

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