Java中的集合及深拷贝与浅拷贝

这篇具有很好参考价值的文章主要介绍了Java中的集合及深拷贝与浅拷贝。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java中的集合及深拷贝与浅拷贝

Java是一种面向对象的编程语言,其中集合是常用的数据结构之一,具有方便快捷的特点。在Java开发中,我们常常需要对集合进行复制(拷贝)操作。但是,拷贝操作并不是简单的复制,而应该分为浅拷贝和深拷贝两种不同的方式,本文将分别介绍Java中集合的浅拷贝和深拷贝实现方法。

集合简介

Java中的集合是一种用于存储对象的容器,其中包括List、Set、Map等多种类型。集合的特点是可以动态地增加、删除和修改其中的元素。Java中的集合框架分为两个接口:Collection和Map,其中Collection是所有集合接口的根接口,其常用的子接口包括List、Set和Queue。Map接口表示键-值映射,常用的实现类有HashMap和TreeMap。

java集合深拷贝,SpringBoot 教程,java

浅拷贝

浅拷贝是指拷贝对象时,只复制对象的引用而不是对象本身。这意味着拷贝后的对象与原始对象共享同一个内存地址,对于引用类型的成员变量,拷贝后的对象和原始对象都指向同一个实例。

在Java中,可以通过调用Object类的clone()方法实现浅拷贝。该方法会复制对象的字段,但是对于引用类型的字段,仅复制其引用,而不会复制引用指向的对象。

下面是一个示例代码,演示了如何使用clone()方法实现集合的浅拷贝。

import java.util.ArrayList;
import java.util.List;

class Person implements Cloneable {
    private String name;
    private int age;
    private List<String> hobbies;

    public Person(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class ShallowCopyDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        List<Person> list1 = new ArrayList<>();
        List<String> hobbies = new ArrayList<>();
        hobbies.add("reading");
        hobbies.add("swimming");
        Person person1 = new Person("Tom", 20, hobbies);
        list1.add(person1);
        List<Person> list2 = (List<Person>) ((ArrayList<Person>) list1).clone();
        System.out.println(list1 == list2);
        System.out.println(list1.get(0) == list2.get(0));
        System.out.println(list1.get(0).getHobbies() == list2.get(0).getHobbies());
    }
}

在上面的示例代码中,我们创建了一个Person类,其中包含一个List类型的成员变量hobbies。然后,我们创建了一个List类型的集合list1,并向其中添加一个Person对象person1。接着,我们通过调用list1的clone()方法创建了一个新的集合list2,然后比较list1和list2、person1和list2中的Person对象以及person1和list2中的Person对象的hobbies是否相同。可以看到,由于是浅拷贝,list1和list2、person1和list2中的Person对象及其hobbies都是共享同一块内存空间的。

深拷贝

与浅拷贝不同,深拷贝是指拷贝对象时,不仅复制对象的引用,而且复制引用指向的对象,即创建一个全新的对象,并将原始对象中的所有字段值复制到新对象中。这样做的好处是,新对象和原始对象之间不存在任何关联,对新对象的修改不会影响原始对象。

在Java中,实现深拷贝的方法有多种,下面介绍两种常用的方式。

1. 序列化与反序列化

Java中的序列化可以将对象转换为字节流,而反序列化则可以将字节流还原为对象。利用这一特性,我们可以通过将对象序列化为字节流,然后再反序列化成新对象的方式实现深拷贝。

下面是一个示例代码,演示了如何使用序列化和反序列化实现集合的深拷贝。

import java.io.*;
import java.util.ArrayList;
import java.util.List;

class Person implements Serializable {
    private String name;
    private int age;
    private List<String> hobbies;

    public Person(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }
}

public class DeepCopyDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        List<Person> list1 = new ArrayList<>();
        List<String> hobbies = new ArrayList<>();
        hobbies.add("reading");
        hobbies.add("swimming");
        Person person1 = new Person("Tom", 20, hobbies);
        list1.add(person1);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(list1);
        oos.flush();
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        List<Person> list2 = (List<Person>) ois.readObject();
        System.out.println(list1 == list2);
        System.out.println(list1.get(0) == list2.get(0));
        System.out.println(list1.get(0).getHobbies() == list2.get(0).getHobbies());
    }
}

在上面的示例代码中,我们创建了一个Person类,其中包含一个List类型的成员变量hobbies。然后,我们创建了一个List类型的集合list1,并向其中添加一个Person对象person1。接着,我们通过将list1序列化为字节流,然后再将字节流反序列化为新的List对象list2,实现了深拷贝。最后,我们比较list1和list2、person1和list2中的Person对象以及person1和list2中的Person对象的hobbies是否相同。可以看到,由于是深拷贝,list1和list2、person1和list2中的Person对象及其hobbies均不是共享同一块内存空间的。

2. 手动递归拷贝

手动递归拷贝是另一种实现深拷贝的方式,其思路是先创建一个空的新对象,然后递归地复制原始对象中的所有字段值到新对象中。对于引用类型的字段,需要继续递归拷贝其指向的对象,直到所有字段值均被复制到新对象中。

下面是一个示例代码,演示了如何使用手动递归拷贝实现集合的深拷贝。

import java.util.ArrayList;
import java.util.List;

class Person {
    private String name;
    private int age;
    private List<String> hobbies;

    public Person(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
    }

    public String getName() {
        return name;
    }

    publicvoid setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public Person deepCopy() {
        List<String> newHobbies = new ArrayList<>();
        for (String hobby : hobbies) {
            newHobbies.add(hobby);
        }
        return new Person(name, age, newHobbies);
    }
}

public class DeepCopyDemo2 {
    public static void main(String[] args) {
        List<Person> list1 = new ArrayList<>();
        List<String> hobbies = new ArrayList<>();
        hobbies.add("reading");
        hobbies.add("swimming");
        Person person1 = new Person("Tom", 20, hobbies);
        list1.add(person1);
        List<Person> list2 = new ArrayList<>();
        for (Person person : list1) {
            list2.add(person.deepCopy());
        }
        System.out.println(list1 == list2);
        System.out.println(list1.get(0) == list2.get(0));
        System.out.println(list1.get(0).getHobbies() == list2.get(0).getHobbies());
    }
}

在上面的示例代码中,我们创建了一个Person类,其中包含一个List类型的成员变量hobbies。然后,我们创建了一个List类型的集合list1,并向其中添加一个Person对象person1。接着,我们通过手动递归拷贝的方式,创建了一个新的集合list2,并将list1中的所有Person对象递归拷贝到list2中。最后,我们比较list1和list2、person1和list2中的Person对象以及person1和list2中的Person对象的hobbies是否相同。可以看到,由于是深拷贝,list1和list2、person1和list2中的Person对象及其hobbies均不是共享同一块内存空间的。

总结

在Java中,集合是一种常用的数据结构,而集合的拷贝操作又分为浅拷贝和深拷贝两种方式。浅拷贝只复制对象的引用,而深拷贝则复制引用指向的对象,创建一个全新的对象。实现浅拷贝可以通过调用Object类的clone()方法或者手动复制对象的字段实现,而实现深拷贝可以通过序列化与反序列化或者手动递归拷贝实现。在实际开发中,我们应该根据具体情况选择合适的拷贝方式,以保证代码的正确性和性能。文章来源地址https://www.toymoban.com/news/detail-732903.html

到了这里,关于Java中的集合及深拷贝与浅拷贝的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【python 深拷贝与浅拷贝】

    python 深拷贝与浅拷贝 在用影刀编写流程的时候发现,明明只修改人名为“小张”对应的字典里面的值,但是所有的人名对应的值都被修改了。 第14行,设置键值对,值对应的变量“初始打卡类型字典”是前面流程生成的,还是引用了原来的地方。 用python来复现: 1、如果列

    2024年02月05日
    浏览(38)
  • JS之深拷贝与浅拷贝

     深拷贝 与 浅拷贝  针对于 引用类型(Object,Array,Function) 来说的 浅拷贝:在栈中分配一块新内存,拷贝需要拷贝的值,           对简单数据类型,就是拷贝值;对复杂数据类型,就是拷贝了一份栈内存储的堆内存的地址  深拷贝:在堆中重新分配新内存,存储新的拷贝数据

    2024年02月09日
    浏览(46)
  • 一文道破Java中的深拷贝,浅拷贝,零拷贝

    在Java编写代码中,对象的拷贝是一个常见的操作。根据拷贝的层次和方式不同,可以分为深拷贝、浅拷贝和零拷贝。本篇文章我们将详细介绍这三种拷贝方式的概念、实现方法以及使用场景,方便大佬学习及面试。 深拷贝是一种创建对象副本的方法,其中新对象与原始对象

    2024年02月04日
    浏览(37)
  • Java中的浅拷贝与深拷贝

    在Java中,对象的拷贝有两种方式:浅拷贝和深拷贝。它们分别代表了不同的拷贝方式,拷贝出的新对象与原始对象之间存在一定的差异。本文将详细介绍浅拷贝和深拷贝的概念、特点和实现方式,并且通过实例进行解析。  一、浅拷贝  浅拷贝是指在对一个对象进行拷贝时,

    2024年02月14日
    浏览(39)
  • 面试官:深拷贝与浅拷贝有啥区别?

    首先,明确一点深拷贝和浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这个时候你修改两者中的任何一个的值都不会影响另一个,而对象或者引用数据来说在进行浅拷贝

    2024年02月07日
    浏览(39)
  • 【Python】python深拷贝与浅拷贝详解(必须掌握)

    深拷贝和浅拷贝是python必须要掌握的内容,无论你是面试开发、测试、运维等职位,只要是python,深拷贝与浅拷贝是面试官常问的一个重要知识点。 (关注“测试开发自动化” 弓中皓,获取更多学习内容) 相同点: 无论深拷贝还是浅拷贝都会创建一个新对象。即:拷贝出来

    2024年03月25日
    浏览(42)
  • 深入探索前端之道:JavaScript深拷贝与浅拷贝的解析与实现

    前端开发中,数据的复制是一个常见的操作。尤其是在处理对象和数组时,我们需要考虑的是一个浅拷贝还是深拷贝。那么,什么是深拷贝和浅拷贝?它们在前端开发中有什么作用?如何实现这两种拷贝?这是我们在本文将讨论的问题。 浅拷贝 浅拷贝是一种数据复制方式,

    2024年02月10日
    浏览(37)
  • 对java中的List进行深拷贝,并进行删除测试

    ListString list = new ArrayList();  // 需要拷贝的原始List list.add(\\\"aaa\\\"); list.add(\\\"bbb\\\"); list.add(\\\"ccc\\\"); ListString listNew = new ArrayList();  // 新List // 将原始List的值赋值给新List CollectionUtils.mergeArrayIntoCollection(new Object[list.size()], listNew); Collections.copy(listNew, list); // 现在将心List中的值删除一个,会

    2024年02月11日
    浏览(29)
  • Java中的集合类

    一. 介绍 在Java中,集合是一种用于存储和操作多个元素的容器。它更方便地操作和管理一组对象,集合类提供了比传统的数组更强大和灵活的功能,可以动态地添加、删除和查找元素,以及进行排序、过滤等操作。集合类有一个共同特点,就是它们只容纳对象,如果想在集合

    2024年02月16日
    浏览(34)
  • java中的集合

    Java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中。 Collection 接口-定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。 Set 中的数据对象没有顺序且不可以重复。 List 中的数据对象有顺序且可以重复。  List继承了Collection接口,有三个实

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包