32
loading...
This website collects cookies to deliver better user experience
listOf
function, which takes a variable number of arguments, and those become the elements of your list. Even in this blog post series, we've created a list like that about a hundred times:listOf(1, 2, 3, 4, 5)
// [1, 2, 3, 4, 5]
List
constructor function. Here, we pass two parameters – the size
of the list, and an init
function that creates each of the elements in our list. That function we pass gets the element index as its parameter, which we can use to adjust the item content:List(5) { idx -> "No. $idx" }
// [No. 0, No. 1, No. 2, No. 3, No. 4]
toList
method."word-salad".toList()
// [w, o, r, d, -, s, a, l, a, d]
toList
on that to get a list of key-value pairs:mapOf(
1 to "Gold",
2 to "Silver",
3 to "Bronze"
).toList()
// [(1, Gold), (2, Silver), (3, Bronze)]
toList
. As an example, we can consider a random sequence of numbers, or the inclusive integer range from zero to ten:generateSequence {
Random.nextInt(100).takeIf { it > 30 }
}.toList()
// [73, 77, 69, 79, 71, 64]
(0..10).toList()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
toList
on something that already is a list. This creates brand-new copy of the original list. We can see this in the following example, where we create a mutable list with a few numbers. By calling toList
, we obtain a new working copy:val list = mutableListOf(1, 2, 3)
val otherList = list.toList()
list[0] = 5
println(list)
// [5, 2, 3]
println(otherList)
// [1, 2, 3]
get
function, together with an index:val myList = listOf("🍔", "🌭", "🍕")
myList.get(1) // 🌭
.get
manually, you’ll see that IntelliJ IDEA already gives you the helpful hint to use some much more popular syntactic sugar for it – the indexed access operator, denoted by the brackets with an index:myList[1] // 🌭
get
function which we can explore. Two of those that come to mind are getOrElse
and getOrNull
. They help us handle cases where we might be accessing an index that falls out of bounds (which can either be a negative index, or an index that’s larger than the last index in our collection.)myList[3]
// Index 3 out of bounds for length 3
val myList = listOf("🍔", "🌭", "🍕")
myList.getOrNull(3)
// null
myList.getOrElse(3) {
println("There's no index $it!")
"😔"
}
// There's no index 3!
// 😔
val listOfNullableItems = listOf(1, 2, null, 4)
val x: Int = listOfNullableItems[0] ?: 0
take
and drop
functions that were introduced in the Diving into Kotlin collections post.slice
function!0, 2, 4
, and get those items from our list of letters:val myList = listOf("a", "b", "c", "d", "e")
myList.slice(listOf(0, 2, 4))
// [a, c, e]
IntRange
s or progressions to specify the indexes. For example, we could request “all items from 0 through 3”, or specify a custom step-size of 2. We could even pull out some items in reverse order, if we create a progression that uses downTo
:myList.slice(0..3)
// [a, b, c, d]
myList.slice(0..myList.lastIndex step 2)
// [a, c, e]
myList.slice(2 downTo 0)
// [c, b, a]
MutableList
specializes List
, meaning everything we’ve learned about lists so far also works for their mutable counterpart, plus some extra functionality.mutableListOf
function, with a bunch of values as arguments. And, wherever you were able to find a toList
method, as discussed previously, you’ll probably also find a toMutableList
. That also includes other lists and mutable lists – where you’ll get a fresh copy when calling toMutableList
:mutableListOf(1, 2, 3)
// [1, 2, 3]
(0..10).toMutableList()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
listOf(1, 2, 3).toMutableList()
// [1, 2, 3]
add
function, or by using the +=
operator shorthand, both of which append an item to the end of the list.add
function also accepts an index, which inserts the new element at that position and moves the surrounding elements to accommodate it. In the same way, we can also add a whole other collection to our mutable list:val m = mutableListOf(1, 2, 3)
m.add(4)
m += 4
println(m)
// [1, 2, 3, 4, 4]
m.add(2, 10)
println(m)
// [1, 2, 10, 3, 4, 4]
m += listOf(5, 6, 7)
println(m)
// [1, 2, 10, 3, 4, 4, 5, 6, 7]
remove
function or the -=
operator shorthand, which removes from our collection a single instance of the element we provide. In this example, after calling -= and remove
, we got rid of two of the 3s in our original collection – because each invocation removed one of them.-=
operator a collection of elements. In this case, the operator acts as a shorthand for the removeAll
function. Here, it looks at every element in the collection we pass, and removes all instances of them in our original, mutable collection. (This is an important distinction to make!) So, by passing 1 and 4 as a collection, we remove all instances of those numbers from our mutable list, and we’re left with only 2 and 3 at the end.val m = mutableListOf(1, 2, 3, 3, 3, 4, 4, 4)
m -= 3
m.remove(3)
println(m)
// [1, 2, 3, 4, 4, 4]
m -= listOf(1, 4)
println(m)
// [2, 3]
removeAt
function instead. For example, we could remove the second element in our list, which resides at index 1.val m = mutableListOf(1, 2, 3, 3, 3)
m.removeAt(1)
println(m)
// [1, 3, 3, 3]
set
function with that index and element under the hood, and switches out the item at the specified index – in this case, trading a "b" for an "a".val m = mutableListOf("a", "b", "c", "d", "e")
m[1] = "a"
println(m)
// [a, a, c, d, e]
fill
function, which replaces each element with the same value we specify. If we look at a list of fruits, for example, and suddenly realize that all of them are really just sugar, we use fill to replace them with candy (🍬). While that metaphor may not be entirely scientifically accurate, it's tasty nonetheless!clear
function can help with removing all elements from a collection – in our case, getting rid of all the candy:val fruits = mutableListOf("🍉", "🍊", "🥝")
// wait, it's all sugar?
fruits.fill("🍬")
println(fruits)
// [🍬, 🍬, 🍬]
// ... nom nom
fruits.clear()
println(fruits)
// []
sorted
, shuffled
, and reversed
. However, those don’t modify the original collection.sort()
instead of sorted()
, shuffle()
instead of shuffled()
, and reverse()
instead of reversed()
functions:val list = listOf(3, 1, 4, 1, 5, 9)
list.shuffled()
list.sorted()
list.reversed()
println(list)
// [3, 1, 4, 1, 5, 9]
val m = list.toMutableList()
m.shuffle()
println(m)
// [5, 1, 1, 3, 4, 9]
m.sort()
println(m)
// [1, 1, 3, 4, 5, 9]
m.reverse()
println(m)
// [9, 5, 4, 3, 1, 1]
removeAll
function can remove all elements that match the predicate we specify. Let’s say we’re not a fan of small numbers in our collection, and only want to keep numbers that are 5 or above – removeAll
helps us do exactly that.val numbers = mutableListOf(3, 1, 4, 1, 5, 9)
numbers.removeAll { it < 5 }
println(numbers)
// [5, 9]
retainAll
function is the opposite, and only keeps those elements in the mutable list that match. If we want to retain every character in our collection that is a letter, we do that with the retainAll
function:val letters = mutableListOf('a', 'b', '3', 'd', '5')
letters.retainAll { it.isLetter() }
println(letters)
// [a, b, d]
subList
function, which takes a beginning and end index, which determines which elements should be “visible” in the view. By having a look at an example sublist, we can see that it contains the elements from our original collections based on the indices we specify (with the upper bound being exclusive):val fruits = mutableListOf("🍉", "🍊", "🥝", "🍏")
val sub = fruits.subList(1, 4)
println(sub)
// [🍊, 🥝, 🍏]
fruits
list, then our sublist will reflect that change:fruits[1] = "🍌"
println(sub)
// [🍌, 🥝, 🍏]
sub[2] = "🍍"
println(fruits)
// [🍉, 🍌, 🥝, 🍍]
sub.fill("🍬")
println(fruits)
// [🍉, 🍬, 🍬, 🍬]
subList
has just given us a different perspective on that list!subList
to have undefined behavior.asReversed
function. It provides a backwards view of the underlying list. Once again, changes made in the view are visible in the original collection, and vice versa. As you can see in the following example, turning the orange into a banana in our original list also changes what we see in the reversed view. Altering it back to a pineapple via our reversed view also alters our original mutable list:val fruits = mutableListOf("🍉", "🍊", "🥝", "🍏")
val stiurf = fruits.asReversed()
println(stiurf)
// [🍏, 🥝, 🍊, 🍉]
fruits[1] = "🍌"
println(stiurf)
// [🍏, 🥝, 🍌, 🍉]
stiurf[2] = "🍍"
println(fruits)
// [🍉, 🍍, 🥝, 🍏]
getOrNull
and getOrElse
functions.