Difference between List.subList and slice in Kotlin

13,615

The key in List<T>.slice function is the .toList() at the end.
The call to toList() will create a new List with all the elements, like a copy.

For summary:

  • .slice() will create a new List with the subset of elements
  • .subList() is only a view of the original List that will change with it.

You can see differences here: https://pl.kotl.in/-JU8BDNZN

fun main() {
    val myList = mutableListOf(1, 2, 3, 4)
    val subList = myList.subList(1, 3)
    val sliceList = myList.slice(1..2)
    println(subList) // [2, 3]
    println(sliceList) // [2, 3]

    myList[1] = 5
    println(subList) // [5, 3]
    println(sliceList) // [2, 3]
}
Share:
13,615
Farbod Salamat-Zadeh
Author by

Farbod Salamat-Zadeh

Updated on June 16, 2022

Comments

  • Farbod Salamat-Zadeh
    Farbod Salamat-Zadeh almost 2 years

    I recently realised there are two very similar functions in Kotlin for getting a portion of a List, but I'm unsure of the difference:

    The documentation for List.subList says:

    Returns a view of the portion of this list between the specified fromIndex (inclusive) and toIndex (exclusive). The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa.

    Structural changes in the base list make the behavior of the view undefined.

    whereas the documentation for slice says:

    Returns a list containing elements at indices in the specified indices range.

    Or

    Returns a list containing elements at specified indices.

    It seems that the key differences are that the first one returns a "view of the portion" of the list, and whether non-structural changes are reflected? However I'm not quite sure what this means.

    I looked at the source code for the slice function:

    public fun <T> List<T>.slice(indices: IntRange): List<T> {
        if (indices.isEmpty()) return listOf()
        return this.subList(indices.start, indices.endInclusive + 1).toList()
    }
    

    But it returns a list from the subList function.

    Could someone explain the differences between these two functions and when you might want to use one over the other?

  • MEX
    MEX over 2 years
    You should be aware, that the list content does not get copied when using slice, but also references the same object. So if you make changes to an object in myList, the changes will also affect the object in sliceList, since it's the same object. You can checkout this sample here pl.kotl.in/AFbm6dWXf