Is Iterable.toList guaranteed to make a copy?


Is Iterable.toList guaranteed to make a (shallow) copy? Even if the Iterable in question is already a list?

If yes, is this documented somewhere?

If not (or maybe even if yes…), what is the idiomatic way to make a shallow copy of a collection?


Maybe something like { it }


toList could return the same instance if the Iterable is actually an immutable list. Otherwise it returns a shallow copy.

fun main() {
    val list = emptyList<Any>()
    val list2 = list.toList()
    println(list === list2)


Thanks for the responses!

Out of curiosity, what constitutes an “immutable list”? The above example prints “false” if I replace the first line with val list = listOf(1, 2, 3)


Based of what I can tell by the implementation

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()

the part about immutable is not true. As long as the list is empty it will always return emptyList() which is a singleton object. In all other cases it should be a shallow copy. (Well I guess EmptyList is immutable but yeah :wink:)

The code is from kotlin 1.3.11but I don’t think this part has changed since 1.0 and probably never will.


No, it shouldn’t. It is currently, but nothing says that it should necessary be so.

We don’t have the means to determine if a list is actually immutable, but when we do toList implementation will just return the receiver for such lists:

if (this is ImmutableList) return this


You’re right. I didn’t mean to imply that it’s guaranteed. I just meant to say that it currently returns a copy in those cases.

I’d be interested to see how this could be achieved. I guess you could check for whether some ImmutableList interface is present, but that would only catch kotlin implementations. This wouldn’t for example catch Guavas immutable lists. I guess you will only support the immutable types from this KEEP.