针对集合、map浅拷贝深拷贝的问题分析(以实际代码说明)

前言:

区别:

浅拷贝:直接引用原对象的内存地址,导致修改复制后的对象,原对象也被修改

深拷贝:重新在栈、堆中开辟空间,内存地址不一样,内部存放的数据一样,修改复制后的对象,原对象不会影响。

那么本文就是针对常见的针对集合、map的复制方法,探究他们是浅拷贝还是深拷贝!

集合的浅、深拷贝

1. 浅拷贝:BeanUtils.copyProperties:

该方法首先是不能复制集合的:

 其次该方法是浅拷贝:

接着

不管是:org.springframework.beans.BeanUtils

还是:org.apache.commons.beanutils.BeanUtils

都是浅拷贝

2. 浅拷贝:Collections.copy

  //测试3: Collections.copy(list2, list1);
        List<Student> list1 = new ArrayList<>();
        List<Student> list2 = new ArrayList<>();
        for (int i = 0; i < 1; i++) {
            list2.add(null); // 必须手动把list2的长度增加到10,否则拷贝了之后list2长度仍是0
        }

        for (int i = 0; i < 1; i++) {
            Student student = new Student(i, "a");
            list1.add(student);
        }
        System.out.println("List1:"+ list1);
        list1.stream().forEach(System.out::println);
        Collections.copy(list2, list1);
        System.out.println("List2:" + list2);
        list2.stream().forEach(System.out::println);
        list1.get(0).setName("测试");
        System.out.println("List1修改之后:" );
        list1.stream().forEach(System.out::println);
        System.out.println("List2在list1修改之后:" );
        list2.stream().forEach(System.out::println);

 注意:

BeanUtils.copyProperties(list1, list2); 若list2的长度为空吗,则复制后list2还是为空,需要你手动吧list的长度填充为list1长度一样。【我觉得这里巨离谱】

3. 浅拷贝:List target = new ArrayList<>(listSource)

同样是浅拷贝

4. 深拷贝:序列化的方式

序列化的方式可以实现深拷贝,代码如下:

    public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);

        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream in = new ObjectInputStream(byteIn);

        List<T> copy_list = (List<T>) in.readObject();
        return copy_list;
    }

 不知道你觉得麻不麻烦?所以一下给出用Stream流的方式实现集合的深拷贝、

5. 深拷贝:Stream流

 List<Student> list2 = new ArrayList<>();
        list1.stream().forEach(item->{
            //每一次new 一个新的对象放进去就行了
            Student student = new Student();
            BeanUtils.copyProperties(student,item);
            list2.add(student);
        });

个人理解:深拷贝不就是使得拷贝后的元素的地址指向和拷贝前的地址不一样嘛,那直接每次new一个对象放进去就行了

map的浅、深拷贝

1.  浅拷贝:= 方式 

2. 特殊情况:putall的方式

首先putall,对于map内部存放的内容来说是浅拷贝,但是一般写程序的时候,map内部的引用对象一般不会修改的吧,所以如果存在map拷贝的情况,在对于map内部的对象不存在修改的情况下是可以使用的。

  

其次假如真有修改内部对象的需求,那么可以采用Stream流的方式,在拷贝对象的时候,new 1个新对象放进map中

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值