打造不可变集合优化之对象拷贝

打造不可变集合优化之对象拷贝

前序
      在上一篇打造不可变集合的博客中说到,关于集合复制的优化。

Collections.copy(copyList,list);

      上面的方法,是浅拷贝,会存在当引用层次比较深的时候,仍旧存才不可变集合中内容可变的情况,比如下面的代码:
实体类的初始化

Student student = new Student();
HashMap<String, Object> friendMap = new HashMap<>();
Person qwe = new Person(new Doctor("qwe"));
friendMap.put("qwe", qwe);
student.friendMap = friendMap;

      不可变集合可变操作如下:

		Doctor doctor = new Doctor("qwe");
        Person person = new Person(doctor);
        ArrayList<Person> persons = new ArrayList<>();
        persons.add(person);
        
        ArrayList<Object> copyList = new ArrayList<>(Arrays.asList(new Object[10]));
        Collections.copy(copyList,persons);

        doctor.name = "asd";

我们会发现,当doctor的内容更改时,copyList集合里面的内容也会更改,这样就达不到我们要求的不可变集合了。

我们需要深度拷贝
      第一种,clone的方式。
      此方式如果要达到深度拷贝的话,实体类需要实现Cloneable接口,并且重写clone方法。
       有两个缺点:
      1、耦合度太高,如果实体类引用类型的属性有变动,就需要修改clone的方法
      2、如果引用层级比较深的话,要重写多个clone方法,工作量大。
      所以我们不采用这用方法实现深度拷贝。
      第二种,序列化的方式。
      我们经常理解的便是java自带的序列化(完美的选择)

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(student);

        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
        Student copyStudent = (Student)objectInputStream.readObject();

      这种方法对实体类的要求只有一点,就是要实现Serializable接口。

      另外,也可以使用json字符串序列化的形式,深度复制对象。
      但是存在一定的缺陷,比如下面的代码:

String stringStudent = JSON.toJSONString(student);
Student Jsonstudent = JSONObject.parseObject(stringStudent, Student.class);```

      使用fastJson,其中引用层级:student–>list–>person–>doctor,
      序列化为字符串的时候没有问题,
      但是解析为对象的时候,doctor会解析成一个JsonObject(底层是一个Map)。这时当我们使用到doctor的时候就会报如下错误了:
      这是fastJson的一个坑,请铭记。

java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.example.doman.Person
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值