java arraylist拷贝_[Java]ArrayList的深拷贝与浅拷贝

最近在刷Leetcode,里面经常用到ArrayList,对于ArrayList的拷贝也是弄得不是很明白。

ArrayList的拷贝方法有很多,其中大部分都是浅拷贝,例如通过构造函数方法拷贝,

1 List l2 = new ArrayList<>(l1);

或者addAll方法:

1 List l2 = new ArrayList<>();2 l2.addAll(l1);

这些都是浅拷贝,其中clone()方式有些特殊,最开始我以为通过clone()是实现深拷贝,因为我看很多题解都是用这种方式进行拷贝。但其实clone()也是浅拷贝,原因如下:

238b6eecddd46d62435fa33eaa475be1.png

之所以题解经常用clone()或者构造方法直接进行复制,是因为做题通常是Interger或者String类型的List,Interger和String类型都是不可变类,那么只需要通过浅拷贝拷贝一层即可。

而后,我看一些文章写深拷贝方法,其中有一个比较特殊。

例如有一个Person类如下:

static classPerson implements Cloneable{intage;public Person(int age){this.age =age;}

@Overrideprotected Object clone() throwsCloneNotSupportedException {return super.clone();

}

}

通过以下代码,可以实现深拷贝;

List l3 = new ArrayList<>();

List l4 = new ArrayList<>();for(Person person:l3)

l4.add((Person)person.clone());

但是这样的说法不准确,这样的代码只是多拷贝了一层,如果Person类改成如下,这样的拷贝就不成立了。

static class Person implementsCloneable{inta;

Age age;public Person(int a){this.a =a;}

@Overrideprotected Object clone() throwsCloneNotSupportedException {return super.clone();

}

}

40523b8fb71944e3c6372133373639a1.png

虽然完成了对Person的拷贝,改变person2的属性值不会影响到person1,但是person1和person2引用的Age对象是同一个,也就是没有实现深拷贝。

后来发现,在实际场景中,在代码逻辑层面想要完全实现深拷贝非常困难,因为难免会碰到有一些类套娃套了很多层。于是经过继续看一些文章,发现使用序列化方法可以实现深拷贝。

这段代码来自其他文章

1 public static List deepCopy(List src) throwsIOException, ClassNotFoundException {2 ByteArrayOutputStream byteOut = newByteArrayOutputStream();3 ObjectOutputStream out = newObjectOutputStream(byteOut);4 out.writeObject(src);5

6 ByteArrayInputStream byteIn = newByteArrayInputStream(byteOut.toByteArray());7 ObjectInputStream in = newObjectInputStream(byteIn);8

9 List copy_list = (List) in.readObject();10 returncopy_list;11 }

所有需要拷贝到的对象,通通要实现Serializable

static class Person implementsSerializablestatic class Age implements Serializable

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值