JPIyo
JPIyo

Reputation: 75

Immutability issue when casting ArrayList to List in Kotlin

I try to have a deep understanding of collection in Kotlin. I failed keep mutability of List when doing that:

  val intsA = arrayListOf(1, 2, 3)
  val intsB: List<Int> = intsA
  intsA.add(4)
  println("intsA = $intsA && intsB = $intsB")

resulting:

intsA = [1, 2, 3, 4] && intsB = [1, 2, 3, 4]

Yes I know I am passing the reference and I could do it more safely by doing:

val intsB: List<Int> = intsA.toList()

still I do not really understand what is happening behind the scene? Why the default casting in Kotlin is not to done more safely? Because it can be a bit dangerous to have that piece of code somewhere in code and later on use it thinking that it is immutable like here:

fun main(args: Array<String>) {

    val intsA = arrayListOf(1)
    val intsB: List<Int> = intsA
    val myClass = MyClass(intsB)

    intsA.add(2)
    println("intsA = $intsA && intsB = $intsB && myClass = $myClass")

}

class MyClass(val list: List<Int>){
    override fun toString(): String {
        return "MyClass(list=$list)"
    }
}

resulting:

intsA = [1, 2] && intsB = [1, 2] && myClass = MyClass(list=[1, 2])

Upvotes: 3

Views: 1805

Answers (2)

Erik Pragt
Erik Pragt

Reputation: 14617

A val doesn't mean a list is immutable. It just means the reference can't be changed. There is no immutability in the code you have provided. What you probably wanted to do was use listOf (which creates an immutable List) instead of arrayListOf, which creates an instance of ArrayList, which is mutable.

Btw, Kotlin itself doesn't provide support for immutable collections yet, but this might be implemented one day.

Upvotes: 0

zsmb13
zsmb13

Reputation: 89548

The .toList() call isn't some fancier cast that enables this "immutabilty". That function simply constructs an entirely new List internally, and copies the elements from the original list into the new one. That's why modifications to the original no longer affect the new list.


As for why it's possible to have a reference to the same list both as a List and a MutableList - this really is a basic feature of OOP. You can expose the same object through various interfaces for your different clients, with different operations available on them.

Upvotes: 5

Related Questions