Lists are one of the most common data structures in computer programming because they allow us to group related data into a single object. For example, we may make a list of each letter of the alphabet. We would need 26 variables, one for each letter, without a list. However, a list lets us create a single object that holds all 26 letters of the alphabet.
Kotlin has two forms of lists. One is a read-only list and the other is a mutable list. The read-only list is created once and only allows operations that do not change the list. For example, we are free to look at each element in such a list, but we may not add or remove elements or sort the list. Such operations would change the list. We are free to iterate through a read-only list and look for elements that match certain criteria, but we may not reassign certain members of the list.
Mutable lists support all operations found in a read-only list be we may also modify the list itself. So we are free to sort a mutable list, add items to it, or remove items. We may even reassign elements at certain indexes. Both styles of lists have methods that facilitate conversion between one form of a list to the other.
Read Only Lists
Creation
We create a read only list using the listOf() function and passing any number of arguments to the function.
val family = listOf("Bob", "Linda", "Tina", "Gene", "Lousie") val numbers = listOf(1, 2, 3, 4) val anyList = listOf<Any>(1, "Linda", 1.0) val nullList = listOf<String?>("Teddy", "Mort", null)
The Kotlin compiler is usually able to figure out the type of the list, but in cases of mixed types, we may need to explicity specify the type of objects the list can hold. Lists hold non-null values by default, so if we need the list to store nulls, we need to explicitly tell the list to hold nulls by specifying the type followed by a ‘?’ mark.
Accessing items
Lists overload the index operator [] so we access elements in the list using the index operator.
println(family[0]) //prints Bob
Checking Membership
We can check if an item exists in the list by using the in keyword.
val hasBob = "Bob" in family val hasTeddy = "Teddy" in family println(hasBob) //prints true println(hasTeddy) //prints false
Finding the Max Item
Lists have a max() method that returns the max item in the list.
println(family.max()) //prints "Tina"
Last Item in a List
We can use the last() function to return the last item in a list.
pritnln(family.last()) //prints Louise
Go Through the List
Lists have a forEach method that lets you go through the list one element at a time.
family.forEach( {it -> println(it) } )
The forEach function takes a lambda expression. The “it” variable refers to the current item in the list.
Mutable Lists
Mutable Lists have the same functionality as above but also allow for operations that change the list.
Creation
Use the mutableListOf() function to create a mutable list.
val smiths = mutableListOf("Rick", "Jerry", "Beth", "Summer", "Morty")
Adding / Removing Items
We use the add() method to add an item and the remove method to remove an item.
smiths.add("Rick Clone") smiths.remove("Rick Clone") smiths.add("Morty Clone", 0) //insert at index 0 smiths.remove(0) //Remove element at index 0
Sorting
The mutable list also has a handy sort() method.
smiths.sort() //Now the list is sorted in alphabetical order
Conclusion
Kotlin is one of the few languages that distinguishes between read only and read write lists. Read only lists are write protected and only allow non-changing operations. Mutable lists are read and write lists and allow for mutating operations such as adding or removing items. We have demonstrated a few of the more common operations found on lists but there are many more. Please check the Kotlin documentation for more details!