Understanding Kotlin Collections: A Step-by-Step Guide for Beginners and Experts
When programming, it is useful to be able to group data into structures for later processing. Kotlin provides collections for exactly this purpose. One of the key features of Kotlin is its rich set of collection types, which provide developers with a wide range of options for storing and manipulating data. In this blog post, we will explore the various collection types available in Kotlin and discuss their features and use cases.
Introduction to Collections
Collections in Kotlin are used to store and manipulate groups of related objects. Kotlin provides a rich set of collection types that can be broadly categorized into two main categories: read-only collections and mutable collections. Read-only collections are collections that cannot be modified once they are created, while mutable collections are collections that can be modified after they are created.
Kotlin has the following collections for grouping items:
Difference Between Read-Only Collections and Mutable Collections
List
Lists store items in the order that they are added, and allow for duplicate items.
To create a read-only list (List
), use the listOf()
function.
val list = listOf(1, 2, 3, 4, 5)
println(list[0])
// Output: 1
To create a mutable list (MutableList
), use the mutableListOf()
function.
val mutableList = mutableListOf(1, 2, 3, 4, 5)
mutableList.add(6)
println(mutableList)
// Output: [1, 2, 3, 4, 5, 6]
// Mutable list with explicit type declaration
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
println(shapes)
// Output: [triangle, square, circle]
Functions and Operators that can be used with List.
Lists are ordered so to access an item in a list, use the indexed access operator[]:
val readOnlyShapes = listOf("triangle", "square", "circle")
println("The first item in the list is: ${readOnlyShapes[0]}")
// Output: The first item in the list is: triangle
To get the first or last item in a list, use .first()
and .last()
functions respectively:
val colors = listOf("red", "green", "blue")
println("The first item in the list is: ${colors.first()}")
println("The Last item in the list is: ${colors.last()}")
// The first item in the list is: red
// The Last item in the list is: blue
To get the number of items in a list, use the .count()
function:
val colors = listOf("red", "green", "blue")
println("This list has ${colors.count()} items")
// Output: This list has 3 items
To check that an item is in a list, use the in
operator:
val colors = listOf("red", "green", "blue")
println("blue" in colors)
// Output: true
subList
Returns a view of the portion of this list between the specified fromIndex
(inclusive) and toIndex
(exclusive).
val list = listOf(1, 2, 3, 4, 5)
println(list.subList(1, 3))
// Output: [2, 3]
sorted
Returns a new list containing all elements of the original list sorted according to their natural sort order.
val list = listOf(3, 1, 4, 2, 5)
println(list.sorted())
// Output: [1, 2, 3, 4, 5]
size
Returns the size of the list.
val list = listOf(1, 2, 3, 4, 5)
println(list.size)
// Output: 5
contains
Checks if the list contains a specific element.
val list = listOf(1, 2, 3, 4, 5)
println(list.contains(3))
// Output: true
indexOf
Returns the index of the first occurrence of the specified element in the list.
val list = listOf(1, 2, 3, 4, 5)
println(list.indexOf(3))
// Output: 2
sorted
Returns a new list containing all elements of the original list sorted according to their natural sort order.
val list = listOf(3, 1, 4, 2, 5)
println(list.sorted())
// Output: [1, 2, 3, 4, 5]
MutableList Functions
add
: Adds the specified element to the end of the list.
val mutableList = mutableListOf(1, 2, 3, 4, 5)
mutableList.add(6)
println(mutableList)
// Output: [1, 2, 3, 4, 5, 6]
addAll
: Adds all elements from the specified collection to the end of the list.
val mutableList = mutableListOf(1, 2, 3, 4, 5)
mutableList.addAll(listOf(6, 7, 8))
println(mutableList)
// Output: [1, 2, 3, 4, 5, 6, 7, 8]
remove
: Removes the first occurrence of the specified element from the list.
val mutableList = mutableListOf(1, 2, 3, 4, 5)
mutableList.remove(3)
println(mutableList)
// Output: [1, 2, 4, 5]
removeAt
: Removes the element at the specified index from the list.
val mutableList = mutableListOf(1, 2, 3, 4, 5)
mutableList.removeAt(2)
println(mutableList)
// Output: [1, 2, 4, 5]
clear
: Removes all elements from the list.
val mutableList = mutableListOf(1, 2, 3, 4, 5)
mutableList.clear()
println(mutableList)
// Output: []
Set
Whereas lists are ordered and allow duplicate items, sets are unordered and only store unique items.
To create a read-only set (Set
), use the setOf()
function.
// Read-only set
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
println(readOnlyFruit)
// Output: [apple, banana, cherry]
You can see in the previous example that because sets only contain unique elements, the duplicate "cherry"
item is dropped.
To create a mutable set (MutableSet
), use the mutableSetOf()
function.
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")
println(fruit)
// Output: [apple, banana, cherry]
Functions that can be used with Set.
size
: Returns the size of the set.
val set = setOf(1, 2, 3, 4, 5)
println(set.size)
// Output: 5
count()
: Returns the size of the set.
val set = setOf(1, 2, 3, 4, 5)
println(set.count()
// Output: 5
in
: To check that an item is in a set
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
println("banana" in readOnlyFruit)
// Output: true
contains
: Checks if the set contains a specific element.
val set = setOf(1, 2, 3, 4, 5)
println(set.contains(3))
// Output: true
isEmpty
: Checks if the set is empty.
val set = setOf<Int>()
println(set.isEmpty())
// Output: true
union
: Returns a new set containing all elements from both sets.
val set1 = setOf(1, 2, 3)
val set2 = setOf(3, 4, 5)
println(set1.union(set2))
// Output: [1, 2, 3, 4, 5]
intersect
: Returns a new set containing only the elements that are present in both sets.
val set1 = setOf(1, 2, 3)
val set2 = setOf(3, 4, 5)
println(set1.intersect(set2))
// Output: [3]
MutableSet Functions
add
: Adds the specified element to the set.
val mutableSet = mutableSetOf(1, 2, 3, 4, 5)
mutableSet.add(6)
println(mutableSet)
// Output: [1, 2, 3, 4, 5, 6]
addAll
: Adds all elements from the specified collection to the set.
val mutableSet = mutableSetOf(1, 2, 3, 4, 5)
mutableSet.addAll(setOf(6, 7, 8))
println(mutableSet)
// Output: [1, 2, 3, 4, 5, 6, 7, 8]
remove
: Removes the specified element from the set.
val mutableSet = mutableSetOf(1, 2, 3, 4, 5)
mutableSet.remove(3)
println(mutableSet)
// Output: [1, 2, 4, 5]
clear
: Removes all elements from the set.
val mutableSet = mutableSetOf(1, 2, 3, 4, 5)
mutableSet.clear()
println(mutableSet)
// Output: []
Map
Maps store items as key-value pairs.
You access the value by referencing the key.
Every key in a map must be unique so that Kotlin can understand which value you want to get.
You can have duplicate values in a map.
Maps are useful if you want to look up a value without using a numbered index, like in a list.
To create a read-only map (Map
), use the mapOf()
function.
The easiest way to create maps is to use to
between each key and its related value:
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(readOnlyJuiceMenu)
// Output: {apple=100, kiwi=190, orange=100}
When creating maps, Kotlin can infer the type of items stored. To declare the type explicitly, add the types of the keys and values within angled brackets <>
after the map declaration. For example: MutableMap<String, Int>
. The keys have type String
and the values have type Int
.
To create a mutable map (MutableMap
), use the mutableMapOf()
function.
// Mutable map with explicit type declaration
val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(juiceMenu)
// Output: {apple=100, kiwi=190, orange=100}
Functions that can be used with Map.
To access a value in a map, use the indexed access operator[]
with its key:
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println("The value of apple juice is: ${readOnlyJuiceMenu["apple"]}")
// Output: The value of apple juice is: 100
size
: Returns the number of key-value pairs in the map.
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
println(map.size)
// Output: 3
.count()
: Returns the number of key-value pairs in the map.
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println("This map has ${readOnlyJuiceMenu.count()} key-value pairs")
// Output: This map has 3 key-value pairs
containsKey
: Checks if the map contains a specific key.
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
println(map.containsKey("b"))
// Output: true
containsValue
: Checks if the map contains a specific value.
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
println(map.containsValue(2))
// Output: true
To obtain a collection of the keys or values of a map, use the keys
and values
properties respectively:
keys
and values
are examples of properties of an object. To access the property of an object, write the property name after the object appended with a period .
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(readOnlyJuiceMenu.keys)
// Output: [apple, kiwi, orange]
println(readOnlyJuiceMenu.values)
// Output: [100, 190, 100]
MutableMap Functions
put
: Associates the specified value with the specified key in the map.
val mutableMap = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
mutableMap.put("d", 4)
println(mutableMap)
// Output: {a=1, b=2, c=3, d=4}
putAll
: Copies all of the mappings from the specified map to this map.
val mutableMap = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
mutableMap.putAll(mapOf("d" to 4, "e" to 5))
println(mutableMap)
// Output: {a=1, b=2, c=3, d=4, e=5}
remove
: Removes the mapping for the specified key from the map.
val mutableMap = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
mutableMap.remove("b")
println(mutableMap)
// Output: {a=1, c=3}
clear
: Removes all mappings from the map.
val mutableMap = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
mutableMap.clear()
println(mutableMap)
// Output: {}
Difference between List, Set and Map
Kotlin collections provide a powerful and flexible way to store and manipulate data. Whether you need a read-only collection or a mutable collection, Kotlin has you covered with its rich set of collection types. By understanding the differences between read-only and mutable collections and exploring the various collection types available in Kotlin, you can make informed decisions about which collection type to use for your specific use case.
Subscribe to my newsletter
Read articles from Enoch Rathod directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Enoch Rathod
Enoch Rathod
๐ Android Developer | Crafting Code & Connections | Java ๐ Kotlin ๐ Compose| Passionate about innovation & collaboration | Let's connect & learn together!