easiest way to cast a mutable list into a list?
m
easiest way to cast a mutable list into a list?
h
No cast needed?
c
Don’t cast it, use
.toList()
instead. If you cast it, someone else could cast it back to a mutable list and modify it in a place where it should be treated as read-only
v
They could even then, couldn't they?
Effectively at least
Afair you don't get an unmodifiable list from that, just a normal list but with
List
as return type
c
It’s not strictly unmodifiable like an immutable collection, but the return type is a read only list, and the specific implementation may or may not actually be
ArrayList
. But regardless, even if the result of
toList()
is an instance of
ArrayList
(which implements
MutableList
), it’s still a separate instance, and thus prevents changes to the original list
m
I don't have such method 😭
c
Make sure to look at the return types of your function calls.
.add()
does not return a list
βœ… 1
m
oh, you're right. Such a noob lol
it worked, thanks
πŸ™Œ 1
k
If the list is very large so that it is undesirable to copy it by calling
toList()
, then (if you're on the JVM) you can wrap it using
Collections.unmodifiableList(colors) as List<Color>
πŸ‘€ 1
j
Also you should consider builders like
buildList { ... }
if you temporarily need a mutable list during construction but then want the result as
List
. That said, in your specific case you should consider
List(10) { Color.Black } + Color.Transparent
v
That misses a transparent in the beginning πŸ˜‰
βœ… 1
k
But that misses the point Casey Brooks was making: that someone could still cast it back to the
ArrayList
that it is, and modify it. Though I don't usually worry about such things. If a programmer that uses my API wants to be malicious, they can be malicious in many more ways than casting a
List
to a
MutableList
.
πŸ‘Œ 2
j
@Vampire oops I had missed it, then it's not so nice with direct list additions:
listOf(Color.Transparent) + List(10) { Color.Black } + Color.Transparent
. I guess
buildList
would be the best approach here.
@Klitos Kyriacou yeah the idea is that it might not have been a requirement. The question looked like an XY problem. Also, I agree, usually not a thing I think about as long as the compile time type is read-only. If people want to mess up, they will
πŸ‘ 1
k
There are some cases where defensive copying is desirable: for example, an enum's
values()
method returns a newly created array each time it's called. This is because in Java and Kotlin there are no read-only arrays, and the compiler doesn't prevent accidental modification of the returned array's values. But for List, that's different.
j
an enum's values() method returns a newly created array each time it's called
But we're not the ones making defensive copying in business code. In Kotlin we usually deal with lists for this reason. Also incidentally the enum entries will soon be lists πŸ˜„
k
It will be great when the enum entries will be lists. It would have been nice if they were from the very start, but I guess enums appeared in Java before it had the new collections framework (and Kotlin just uses Java's enums)
1327 Views