Android Kotlin Java list clone 深拷贝简单使用

Android Kotlin Java list clone 深拷贝简单使用,第1张

先上通过 clone 深拷贝的使用步骤:

model 先实现 Cloneable, 重写 clone 方法.model 调用 clone 就会生成一个 全新的对象.new 一个新数组 copyList, 遍历 原始数组 oriList, 一个一个添加到 copyList 即可.

talk is cheap, show me the code: 

class MainKotlin {
    @Test
    fun test0() {
        val oriList = ArrayList()
        val model0 = Model(0, "name0")
        val model1 = Model(1, "name1")
        val model2 = Model(2, "name2")
        oriList.add(model0)
        oriList.add(model1)
        oriList.add(model2)


        val copyList = ArrayList()
        oriList.forEach {
            copyList.add(it.clone())
        }
        println("list = $oriList")
        println("copyList = $copyList")

        println("======== change name ========")
        model0.name = "name0 changed"

        println("list = $oriList")
        println("copyList = $copyList")

    }

    class Model(): Cloneable {
        var id: Int? = null
        var name: String? = null

        constructor(id: Int, name: String) : this() {
            this.id = id
            this.name = name
        }

        // 添加 try catch, 防止奇怪的异常
        public override fun clone(): Model {
            return try {
                return super.clone() as? Model ?: Model()
            } catch (e: CloneNotSupportedException) {
                Model()
            }
        }

        override fun toString(): String {
            return "Model(id=$id, name=$name)"
        }
    }
}

输出结果: 

        可以看到 model0 更改 name 时, list 随之改变, copyList 没有改变, 成功~

起因: 

        今天在做单例的时候, 被数据的一些状态整懵了, 虽然想到了可以通过深拷贝解决问题, 但竟然直接使用了 newList.addAll(oldList) ... 结果又排查问题查了半天...才想到 list 中的 model 也是要完全 new 出来才行, model 里面那么多属性, 一个一个赋值太不优雅啦, 在网上查了下可以通过:

clone 解决实现序列化, 通过反序列化 new 出来对象

但序列化整了半天没成功, 就换 clone, 有空再看下序列化怎么整...

注意: 

        java的一个类,如果要使用 Cloneable 实现拷贝功能, 需要先实现这个接口, 然后重写Object的clone方法. 对于类中的引用类型的属性, 需要在clone方法中实现深拷贝, 否则就是浅拷贝.

        属性中有引用对象的话, 引用对象也要实现 Cloneable, 然后这个引用对象也要调用 clone 方法才行...有点麻烦, 得封装一下才好用...后续带封装...

后续待优化: 

        可以把 集合 的深拷贝封装一个函数, 这样调用起来比较方便, 待执行任务...

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/992696.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存