• 引用对象深度复制的简单实现方法


    注:此种方式受fastjson底层影响,在含有long、double等类型的对象复制后再次反序列化时会出现格式转换错误,推荐使用:https://www.cnblogs.com/nvsky/p/13995574.html

    我们有时候会遇到某个List集合循环几次并修改其属性或赋值给其他集合等操作,但当程序运行完会发现,运行的结果并不如预期,有可能第二次循环的时候原List内的数据已经发生了变化,但我们没有直接的去修改原List的内容,比如下面的例子:

    List<DataObject> dataList = new ArrayList<>();
    dataObject1.setId(13);
    dataList.add(dataObject1);
    List<DataObject> newDataList = new ArrayList<>();
    newDataList.add(dataList.get(0));
    DataObject dataObject2 = newDataList.get(0);
    dataObject2.setId(15);

    我们并没有直接修改dataList的数据,而是赋值给新的对象后再操作的新的对象,但执行后发现,dataList的数据也会跟着改变,因为dataObject1是个应用类型对象,它的地址并没有因为赋值到新的集合内而改变,即使你new一个DataObject,然后 = dataObject1或者调用clone方法,地址依然没有改变,这是因为引用类型的对象在复制时只是浅度复制,并没有重新生成一个对象,而基本类型则不会有这个问题。

    那怎么解决这个问题呢?网上有许多方法,比如Cloneable、序列化等等,写起来比较麻烦,并且有时还需要trycatch,这个有一个简单的方法来实现对象的深度复制,那就是利用JSONObject的转换实现,其实也是通过序列化的方式,但不用亲自动手去序列化反序列化:

    JSONObject.parseArray(JSONObject.toJSONString(dataList)).toJavaList(DataObject.Class)

    先将dataList转成jsonString,即序列化,然后再转成jsonArray并转成java对象,即反序列化

    转换前:

     转换后:

     最后提供一下使用这个封装的工具类,两个方法,一个复制单对象,一个复制List集合:

        /**
         * @author: shenzhikui
         * @description: 利用json转换实现变相深度复制
         * @date: 2019/11/7
         * @param data
         * @param tClass
         * @return
         */
        public static <T> T deepCopy(T data, Class<T> tClass){
            T bakData = JSONObject.parseObject(JSONObject.toJSONString(data)).toJavaObject(tClass);
            return bakData;
        }
    
        /**
         * @author: shenzhikui
         * @description: 利用json转换实现变相深度复制 list
         * @date: 2019/11/7
         * @param dataList
         * @param tClass
         * @return 
         */
        public static <T> List<T> deepCopy(List<T> dataList, Class<T> tClass){
            List<T> bakList = new ArrayList<>();
            if(null != dataList && dataList.size() > 0){
                bakList.addAll(JSONObject.parseArray(JSONObject.toJSONString(dataList)).toJavaList(tClass));
            }
            return bakList;
        }

     使用方法:

    List<DataObject> newDataList = deepCopy(dataList,DataObject.class);
  • 相关阅读:
    Delphi TListView刷新闪烁问题
    GO语言下载、安装、配置
    理解领域模型Domain Model
    Competing Consumers Pattern (竞争消费者模式)
    Compensating Transaction Pattern(事务修正模式)
    一致性hash算法简介
    CQRS, Task Based UIs, Event Sourcing agh!
    Circuit Breaker Pattern(断路器模式)
    Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications 云设计模式:云应用的规范架构指导
    Cache-Aside Pattern(缓存模式)
  • 原文地址:https://www.cnblogs.com/nvsky/p/11820274.html
Copyright © 2020-2023  润新知