'Why both immutable and mutable list objects are changed, when I change only the values of the mutable list?
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.
Solution 1:[1]
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.
Solution 2:[2]
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)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Louis Wasserman |
| Solution 2 | Theseus |
