Kotlin中如何克隆或拷贝二维列表,避免修改原列表同步影响副本?
问题原因
你遇到的问题本质是浅拷贝和深拷贝的区别:
- 你之前使用的
ArrayList(peopleAtBlock1.toMutableList())、data class默认的copy()方法都属于浅拷贝:仅复制集合/对象的外层结构,内部嵌套的集合、自定义类实例仍然是引用同一个内存地址的对象。 - 因此你修改
peopleAtBlock1中嵌套的friends里的Person属性时,peopleAtBlock2因为持有同一个引用,也会同步变更。你之前写的copy2方法只处理了最外层Person的拷贝,没有递归处理嵌套的friends属性,所以不生效。
解决方案
实现递归的深拷贝,逐层复制所有嵌套的Person实例和集合:
步骤1:给Person类添加深拷贝方法
fun Person.deepCopy(): Person { return this.copy( // 递归复制friends列表里的每一个Person实例 friends = this.friends.map { it.deepCopy() } ) }
步骤2:实现集合的深拷贝扩展方法
fun ArrayList<Person>.deepCopy(): ArrayList<Person> { return this.map { it.deepCopy() }.toCollection(ArrayList()) }
步骤3:修改测试用例中的拷贝逻辑
将原来的拷贝代码:
val peopleAtBlock2 : ArrayList<Person> = ArrayList(peopleAtBlock1.toMutableList())
替换为:
val peopleAtBlock2 = peopleAtBlock1.deepCopy()
修改完成后,修改peopleAtBlock1的嵌套属性不会再影响peopleAtBlock2,你的测试断言即可正常通过。
内容的提问来源于stack exchange,提问作者nashihu
相关产品推荐
相关产品推荐

