ArrayList调用addAll后修改原列表新列表同步变动如何解决
问题根因
addAll 方法仅会复制集合中存储的对象引用,不会复制对象本身。你操作的两个集合中对应索引的元素指向同一个内存实例,因此修改任意一个引用指向的对象属性,另一个引用访问到的属性自然会同步变更。
解决方案
核心逻辑是给arrayList1的每个元素生成完全独立的深克隆实例,再把克隆实例添加到arrayList2中,常见实现方式如下:
- 方式1:手动实现深克隆方法(性能最优,推荐)
给元素类增加深克隆方法,注意如果类包含可变引用类型属性(如你代码中的数组arrayCoordinates),需要同时克隆这些属性,不能直接复用原有引用,Kotlin示例如下:
Java场景可以让元素类实现// 示例元素类 data class CustomElement(var arrayCoordinates: Array<Int>) { // 自定义深克隆方法 fun deepCopy(): CustomElement { // 数组也需要复制生成新实例 return CustomElement(arrayCoordinates = arrayCoordinates.copyOf()) } } // 集合添加逻辑修改为:先克隆每个元素再添加 arrayList2.addAll(arrayList1.map { it.deepCopy() })Cloneable接口,重写clone方法实现同样的逻辑。 - 方式2:序列化反序列化实现通用深克隆(适合类结构复杂的场景)
如果元素类属性嵌套多,手动写克隆逻辑成本高,可以通过JSON序列化反序列化的方式生成深克隆实例,示例如下:
注意该方式需要确保元素类支持序列化,性能低于手动实现的克隆方法。val gson = Gson() arrayList2.addAll(arrayList1.map { gson.fromJson(gson.toJson(it), CustomElement::class.java) })
验证效果
修改后的代码执行后,修改arrayList1的元素属性不会再影响arrayList2的元素:
arraylist2.addAll(arrayList1.map { it.deepCopy() }) arraylist2[0].arrayCoordinates // [0, 0] arraylist1[0].arrayCoordinates = arrayOf(1, 1) arraylist2[0].arrayCoordinates // 保持为 [0, 0]
内容的提问来源于stack exchange,提问作者AverageLinuxEnjoyer
相关产品推荐
相关产品推荐

