How can update one element of a list that is a val...
# getting-started
u
How can update one element of a list that is a val of a data class? If the data is something else, say and integer, you'd do
Copy code
myDataClass = myDataClass.copy(myInt = newIntValue)
But say I have
Copy code
MyDataClass(
val listOfInt: List<Int>
)
and I want to update
myDataClass.listOfInt[5]
?
d
There are two possible approaches here: • Use
MutableList
and do
myDataClass.listOfInt[5] = 42
• Keep using immutable
List
. Unfortunately, there's no native way to make a list copy with an updated element, so you will need to create a temporary mutable copy of it, e.g. with this extension
Copy code
fun <T> List<T>.update(index: Int, item: T): List<T> = toMutableList().apply { this[index] = item) }
With that you can write
Copy code
myDataClass.copy(listOfInt = myDataClass.listOfInt.update(5, 42))
u
Thank you! Is there a disadvantage with using a
MutableList
and not using
copy
?
b
Not having to copy over N list elements (thus allocating N new elements on the heap) only to then have the garbage collect destroy the previous N elements. A MutableList would simply mutate the single element in place. The difference between an
O(N)
operation vs
O(1)
u
So that's an advantage?
b
Say theoretically you have computer processor that can do 10.000 things per second. And you have a list of 1000 elements. In the copy implementation you will need to copy over each and every element every time you make an update, costing you a 1000 operations of the 10.000 you have available. In the mutable list implementation you will update in place a single element and be done, costing you 1 operation of the 10.000 you have at your disposal.
u
Yes, and I was wondering whether there was a disadvantage?
b
As with all thing in our field, it depends 😄 Only ever dealing with immutable data does lead to safer code with fewer bugs
☝️ 4
u
Usually when you want to update a data class you use copy, so that's why I'm wondering.
b
So there's always an argument to be made in favour of immutability and data classes
But when one compares implementations and sees one performing linear time and one constant time, usually that's a sign you should pick the one doing constant time
but it always depends
If you are for example sure your list will only ever contain a very small number of elements, the performance difference probably won't even matter
But surely if you need to many times copy over huge lists, your performance will be atrocious
I will add though, against what I am saying above, having a data class, but then internally mutating the contents, is definitely an anti-pattern
d
If you really have a large list but don't do frequent copying, you might want to preserve immutability without paying the O(N) penalty by taking this approach: https://stackoverflow.com/a/74776656/13015027
b
as a data class should signify to whoever reads your code "this is an immutable piece of code", so my suggestion be: 1. Definitely use a MutableList 2. Change your data class to a regular class
e
copying lists isn't really that bad for performance. they only hold references so it's not like all the objects in the list are being copied - they're being shared
but if that's really a concern, then consider https://github.com/Kotlin/kotlinx.collections.immutable - it contains
PersistentList
, which is immutable with efficient copy (using sharing)
1
103 Views