You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ArrayList调用addAll后修改原列表新列表同步变动如何解决

问题根因

addAll 方法仅会复制集合中存储的对象引用,不会复制对象本身。你操作的两个集合中对应索引的元素指向同一个内存实例,因此修改任意一个引用指向的对象属性,另一个引用访问到的属性自然会同步变更。

解决方案

核心逻辑是给arrayList1的每个元素生成完全独立的深克隆实例,再把克隆实例添加到arrayList2中,常见实现方式如下:

  • 方式1:手动实现深克隆方法(性能最优,推荐)
    给元素类增加深克隆方法,注意如果类包含可变引用类型属性(如你代码中的数组arrayCoordinates),需要同时克隆这些属性,不能直接复用原有引用,Kotlin示例如下:
    // 示例元素类
    data class CustomElement(var arrayCoordinates: Array<Int>) {
        // 自定义深克隆方法
        fun deepCopy(): CustomElement {
            // 数组也需要复制生成新实例
            return CustomElement(arrayCoordinates = arrayCoordinates.copyOf())
        }
    }
    
    // 集合添加逻辑修改为:先克隆每个元素再添加
    arrayList2.addAll(arrayList1.map { it.deepCopy() })
    
    Java场景可以让元素类实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 20:24:02