Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between List.subList and slice in Kotlin

Tags:

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?

like image 336
Farbod Salamat-Zadeh Avatar asked Jul 28 '19 12:07

Farbod Salamat-Zadeh


1 Answers

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]
}
like image 136
Kevin Robatel Avatar answered Sep 20 '22 14:09

Kevin Robatel