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

Kotlin列表添加同一对象后修改属性引发条目同步变更问题求助

问题描述

我定义了Boy数据类,将同一个Boy对象多次添加到boysListFinal列表中。修改该对象的name属性后,列表中所有该对象的条目属性都同步变更,无法得到前三个条目保留原属性、第四个条目为修改后属性的预期结果。将对象赋值给新变量后再修改,问题依然存在。

代码示例

data class Boy(var name : String, var age : Int)

fun main() {
    var boysList = arrayListOf<Boy>()
    var boysListFinal = arrayListOf<Boy>()
    val boy1 = Boy("test1234",1)
    boysList.add(boy1)
    for(boy in boysList){
        boysListFinal.add(boy)
        boysListFinal.add(boy)
        boysListFinal.add(boy)
        boy.name = "test1"
        boysListFinal.add(boy)
    }
    println(boysListFinal)
}

实际输出

[Boy(name=test1, age=1), Boy(name=test1, age=1), Boy(name=test1, age=1), Boy(name=test1, age=1)]

预期输出

[Boy(name=test1234, age=1), Boy(name=test1234, age=1), Boy(name=test1234, age=1), Boy(name=test1, age=1)]

尝试的无效代码

fun main() {
    var boysList = arrayListOf<Boy>()
    var boysListFinal = arrayListOf<Boy>()
    val boy1 = Boy("test1234",1)
    boysList.add(boy1)
    for(boy in boysList){
        boysListFinal.add(boy)
        boysListFinal.add(boy)
        boysListFinal.add(boy)        
        val boy2 = boy
        boy2.name = "test1"
        boysListFinal.add(boy2)
    }
    println(boysListFinal)
}
原因分析与解决方案

原因

Kotlin中对象属于引用类型,列表存储的是对象的引用而非对象本身。多次添加同一个Boy对象到列表时,所有条目指向的都是内存中同一个对象实例。修改该对象属性时,所有引用该对象的列表条目都会同步变化。将对象赋值给新变量只是复制了引用,并没有创建新的对象实例,因此问题无法解决。

解决方法

利用Kotlin数据类自带的copy()方法创建对象副本,每个列表条目指向独立的对象实例,修改副本属性不会影响原对象。修改后的代码如下:

data class Boy(var name: String, var age: Int)

fun main() {
    val boysList = arrayListOf<Boy>()
    val boysListFinal = arrayListOf<Boy>()
    val boy1 = Boy("test1234", 1)
    boysList.add(boy1)
    
    for (boy in boysList) {
        // 添加原对象的副本,保留初始属性
        boysListFinal.add(boy.copy())
        boysListFinal.add(boy.copy())
        boysListFinal.add(boy.copy())
        
        // 创建修改后的副本并添加
        val modifiedBoy = boy.copy(name = "test1")
        boysListFinal.add(modifiedBoy)
    }
    
    println(boysListFinal)
}

执行后输出与预期一致:

[Boy(name=test1234, age=1), Boy(name=test1234, age=1), Boy(name=test1234, age=1), Boy(name=test1, age=1)]

内容的提问来源于stack exchange,提问作者Rohit S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:05:41