How does toList() function works

I would like to ask one small question
This is a sample example I was working on to get hands on for the collection function. Its very straight fwd example.

val original = mutableListOf<Char>('a', 'b', 'c', 'd', 'e')


val originalreadOnly = original.toList()

val reversedList = originalreadOnly.asReversed() 

But I have a confusion for toList() function. We are converting an mutableList to ImmutableList, but if I try to check under the sources, toList() returns mutableList instance. But still try to work as immutableList i.e it is not able to add/remove any elements. I do not understand how this works. Following is the underlying source

public fun <T> Iterable<T>.toList(): List<T> {
    if (this is Collection) {
        return when (size) {
            0 -> emptyList()
            1 -> listOf(if (this is List) get(0) else iterator().next())
            else -> this.toMutableList()
        }
    }
    return this.toMutableList().optimizeReadOnlyList()
}

I tried to debug this and this always points to this.toMutableList()
Can someone please help me to understand how does it works. :face_with_hand_over_mouth: :pray::pray:

The type of a variable determines which methods you can invoke on it. original has type MutableList<Char> and originalreadOnly has type List<Char. So even though they point to the exact same instance, the methods that can be invoked differ.

At this moment kotlin uses interfaces to separate a mutableList from a immutableList.
The implementation from the lists come from java and java doesn’t have the immutableLists.
Therefor it’s not possible to differentiate the immutableLists from mutableLists.
Therefor Kotlin chooses that every list implements mutableList as well as immutableList.
Therefor you have to rely on the returntype of a function for knowing if the list can be updated
(Don’t check if a immutableList can be cast to a mutableList, because it can)

Kotlin however has a kotlinx library which implements the immutableLists in Kotlin.
With this library you can really have immutableLists.

(I hope they will replace the default list-implementation soon)

This is not correct. What a MutableList is, is very clear: A list that you are allowed to modify. But List does not indicate immutability at all. It indicates that you are not allowed to modify the list, but that it could still be modified by somebody else.

The kotlinx library may make all Lists immutable, but this is definitely not a requirement of the List interface.

I’d like to clear up some confusion in this thread: List<T> in Kotlin is an interface of a read-only list, rather than immutable one. It provides the operations to read list elements.

The MutableList<T> interface extends the read-only List<T> with the operations to modify list contents.

Therefore an instance of MutableList<T> can be returned where List<T> type is expected.

2 Likes

Thank you