We have a data class:
data class TestObject(
val param1: String,
val param2: String,
var param3: Int?)
and the following code:
val obj1 = TestObject(
param1 = "aaa",
param2 = "aaa",
param3 = null
)
val obj2 = TestObject(
param1 = "aaa",
param2 = "bbb",
param3 = null
)
val obj3 = TestObject(
param1 = "ccc",
param2 = "bbb",
param3 = null
)
val immutableList: List<TestObject> = listOf(obj1, obj2, obj3)
val changeableList = mutableListOf<TestObject>()
val testExercise1 = immutableList.filter { it.param1 == "aaa" }.random()
changeableList.add(0, testExercise1 )
val testExercise2 = immutableList.filter { it.param2 == "bbb" }.random()
changeableList.add(1, testExercise2 )
changeableList[0].param3 = 55
changeableList[1].param3 = 66
For some reason, when the param3 of the changeableList objects is changed, the param3 of the immutableList is changed as well. Why is this happening?
I want the immutableList to stay as it was defined in the beginning, and only change the changeableList.
CodePudding user response:
It's happening because at no point is Kotlin making a copy of your TestObject
s. When you create an immutable list, you're making an immutable holder of your mutable TestObject
type -- and if you change the underlying TestObject
s, they'll change everywhere.
To address this, when you make a copy of the list, you will need to add .map { it.copy() }
-- or, better, just make TestObject
immutable in the first place.
CodePudding user response:
Thanks @Louis for the answer. Just to add the correct code:
val testExercise1 = immutableList.map { it.copy() }.filter { it.param1 == "aaa" }.random()
changeableList.add(0, testExercise1)
val testExercise2 = immutableList.map { it.copy() }.filter { it.param2 == "bbb" }.random()
changeableList.add(1, testExercise2)