Java基础笔记-集合-JavaList复制:浅拷贝与深拷贝方法及区别-《Java笔记》

admin 2025-10-19 01:31:18 编程 来源:ZONE.CI 全球网 0 阅读模式

Java List

List浅拷贝

Java List复制:浅拷贝与深拷贝方法及区别 - 图1众所周知,list本质上是数组,而数组的是以地址的形式进行存储。如上图将list A浅拷贝给list B,由于进行的是浅拷贝,所以直接将A的内容复制给了B,java中相同内容的数组指向同一地址,即进行浅拷贝后A与B指向同一地址。造成的后果就是,改变B的同时也会改变A,因为改变B就是改变B所指向地址的内容,由于A也指向同一地址,所以A与B一起改变。

几种浅拷贝

1、遍历循环复制

  1. List<Person> destList=new ArrayList<Person>(srcList.size());
  2. for(Person p : srcList){
  3. destList.add(p);
  4. }

2、使用List实现类的构造方法

  1. List<Person> destList=new ArrayList<Person>(srcList);

3、使用list.addAll()方法

  1. List<Person> destList=new ArrayList<Person>();
  2. destList.addAll(srcList);

4、使用System.arraycopy()方法

  1. Person[] srcPersons=srcList.toArray(new Person[0]);
  2. Person[] destPersons=new Person[srcPersons.length];
  3. System.arraycopy(srcPersons, 0, destPersons, 0, srcPersons.length);

测试及结果

  1. printList(destList); //打印未改变B之前的A
  2. srcList.get(0).setAge(100);//改变B
  3. printList(destList); //打印改变B后的A

打印结果

  1. 123-->20
  2. ABC-->21
  3. abc-->22
  4. 123-->100
  5. ABC-->21
  6. abc-->22

List深拷贝

Java List复制:浅拷贝与深拷贝方法及区别 - 图2如图,深拷贝就是将A复制给B的同时,给B创建新的地址,再将地址A的内容传递到地址B。ListA与ListB内容一致,但是由于所指向的地址不同,所以改变相互不受影响。

深拷贝的方法

1.使用序列化方法

  1. public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
  2. ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
  3. ObjectOutputStream out = new ObjectOutputStream(byteOut);
  4. out.writeObject(src);
  5. ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
  6. ObjectInputStream in = new ObjectInputStream(byteIn);
  7. @SuppressWarnings("unchecked")
  8. List<T> dest = (List<T>) in.readObject();
  9. return dest;
  10. }
  11. List<Person> destList=deepCopy(srcList); //调用该方法

2.clone方法

  1. public class A implements Cloneable {
  2. public String name[];
  3. public A(){
  4. name=new String[2];
  5. }
  6. public Object clone() {
  7. A o = null;
  8. try {
  9. o = (A) super.clone();
  10. } catch (CloneNotSupportedException e) {
  11. e.printStackTrace();
  12. }
  13. return o;
  14. }
  15. }
  16. for(int i=0;i<n;i+=){
  17. copy.add((A)src.get(i).clone());
  18. }

Java对对象和基本的数据类型的处理是不一样的。在Java中用对象的作为入口参数的传递则缺省为”引用传递”,也就是说仅仅传递了对象的一个”引用”,这个”引用”的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。除了在函数传值的时候是”引用传递”,在任何用”=”向对象变量赋值的时候都是”引用传递”。测试及结果

  1. printList(destList); //打印未改变B之前的A
  2. srcList.get(0).setAge(100);//改变B
  3. printList(destList); //打印改变B后的A
  1. 123-->20
  2. ABC-->21
  3. abc-->22
  4. 123-->20
  5. ABC-->21
  6. abc-->22

在浅复制的情况下,源数据被修改破坏之后,使用相同引用指向该数据的目标集合中的对应元素也就发生了相同的变化。因此,在需求要求必须深复制的情况下,要是使用上面提到的方法,请确保List中的T类对象是不易被外部修改和破坏的。

以太坊cppgolang区别 编程

以太坊cppgolang区别

以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
progolang 编程

progolang

Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
golangn个发送者 编程

golangn个发送者

Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
golang技能图谱 编程

golang技能图谱

从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
评论:0   参与:  6