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

什么是深拷贝和浅拷贝?

在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日

相关文章

  • ora-28000帐户已被锁定的解决方法

    简介 ORA-28000是Oracle数据库中的一个错误代码,表示用户帐户已被锁定。这通常是由于用户多次尝试使用错误的凭据数据库而导致的。在本攻略中,我们将介绍如何解决ORA-28000错误,并提供两个示例说明。 解决方法 以下是解ORA-28000错误的方法: 方法1:解锁用户帐户 可以使用以下命令解锁用户帐户: ALTER USER username A…

    other 2023年5月6日
    00
  • 微信小程序的onlaunch()方法和onshow()方法

    微信小程序的onLaunch()方法和onShow()方法概述 在微信小程序中,onLaunch()方法和onShow()方法是两个重要的生命周期函数。onLaunch()方法在小程序初始化时调用,而onShow()方法在小程序启动或从后台进入前台时调用。这两个方法可以帮助开发者实现小程序的初始化和状态管理。 onLaunch()方法 onLaunch()方…

    other 2023年5月9日
    00
  • javascript数组定义的几种方法

    JavaScript是一种广泛使用的编程语言,数组是其中的一种数据类型。本攻略将介绍JavaScript数组的定义方法,包括字面量、构造函数和Array.from()方法。 字面量定义数组 字面量定义数组最常见的方法,可以使用以下语法: let arr = [element1, element2, …, elementN]; 其中element1到ele…

    other 2023年5月9日
    00
  • Android使用VideoView播放本地视频和网络视频的方法

    Android使用VideoView播放本地视频和网络视频的方法 在Android开发中,可以使用VideoView来播放本地视频和网络视频。下面是详细的攻略,包含两个示例说明。 播放本地视频 要播放本地视频,需要将视频文件放置在Android设备的存储中,并使用VideoView来加载和播放视频。 将视频文件放置在res/raw目录下,或者将视频文件复制到…

    other 2023年8月21日
    00
  • Android自定义DataTimePicker实例代码(日期选择器)

    下面我给你详细讲解“Android自定义DataTimePicker实例代码(日期选择器)”的完整攻略。首先,我们来看一下这个自定义DataTimePicker实例的代码: 1. 导入依赖项 dependencies { implementation ‘com.wdullaer:materialdatetimepicker:4.2.3’ } 2. 添加控件到…

    other 2023年6月25日
    00
  • mybatis-plus 扩展批量新增的实现

    下面是详细讲解“mybatis-plus扩展批量新增的实现”的完整攻略: 1. 什么是mybatis-plus扩展批量新增 mybatis-plus是基于mybatis的增强工具,它提供了更加便捷的开发方式和更全面的功能。其中,mybatis-plus提供的扩展批量新增,是指相对于mybatis自带的批量新增,进行了功能上的增强,采用了mapper.xml方…

    other 2023年6月27日
    00
  • Web前端和JAVA应该学哪个?哪个就业形势更胜一筹?

    Web前端和JAVA学习攻略 1. Web前端学习攻略 Web前端开发是构建用户界面的技术,涉及HTML、CSS和JavaScript等技术。以下是学习Web前端的攻略: a. 学习HTML和CSS HTML是网页的基础,用于定义网页结构。学习HTML标签、元素和属性,以及如何创建网页布局。 CSS用于控制网页的样式和布局。学习CSS选择器、样式属性和盒模型…

    other 2023年7月27日
    00
  • iPhone死机怎么办 苹果手机各机型强制重启方法

    iPhone死机怎么办:苹果手机各机型强制重启方法 原因分析 iPhone死机通常是因为系统或应用程序的故障导致的。这种情况下,我们需要通过强制重启设备来解决问题。 强制重启iPhone的方法 下面是iPhone不同机型强制重启的具体操作步骤。 iPhone X及以后机型 长按侧面的“音量上”和“音量下”按键,直到出现“滑动关机”提示; 松开按键,再长按侧面…

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