Home > Software engineering >  Why both immutable and mutable list objects are changed, when I change only the values of the mutabl
Why both immutable and mutable list objects are changed, when I change only the values of the mutabl

Time:04-08

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 TestObjects. When you create an immutable list, you're making an immutable holder of your mutable TestObject type -- and if you change the underlying TestObjects, 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)
  • Related