Kotlin Collections (Lists, Sets & Maps) | Android Introduction #30

ibrahimcanerdogan
9 min readJan 22, 2024

--

In this reading, you will learn collections & functions…

  • LIST
  • SET
  • MAP

UDEMY COURSE

LIST

List is the most basic type of collection. It represents an ordered list of elements. The same elements can be repeated multiple times. You might use a list to represent products in a shopping cart or delivery method options. The order of elements is preserved, so if you define a list of delivery methods in some configuration, those elements should be displayed in the same order on the payment window.

To create a list, the listOf function is used. The next values are then specified using arguments.

fun main() {
val list = listOf("A", "B", "C")
println(list) // [A, B, C]
}

The result type is List<T>, where “T” is the type of elements in this list. Since the code above consists of a list with string values, the type is List<String>.

fun main() {
val list: List<String> = listOf("A", "B", "C")
println(list) // [A, B, C]
val ints: List<Int> = listOf(1, 2, 3)
println(ints) // [1, 2, 3]
}

The easiest way to add elements to lists is using the plus sign. You can add a single element to a list, or you can add two lists together.

fun main() {
val list = listOf("A", "B")
println(list + "C") // [A, B, C]
println(list + listOf("C", "D")) // [A, B, C, D]
println(listOf("Z") + list) // [Z, A, B]
}

You can always check the number of elements in a list using the size property.

fun main() {
val list = listOf("A", "B", "C")
println(list.size) // 3
}

To check if a list is empty, you can compare its size to 0, or you can use the isEmpty method.

fun main() {
val list = listOf("A", "B", "C")
println(list.size == 0) // False
println(list.isEmpty()) // False

val empty: Set<Int> = setOf()
println(empty.size == 0) // True
println(empty.isEmpty()) // True
}

You can check if a set contains a certain element. For that, you can use the contains method or the in operator. Both of those options return true if in the list there is an element equal to the element you are looking for, and it returns false otherwise.

fun main() {
val letters = listOf("A", "B", "C")
println(list.contains("A")) // true
println(list.contains("Z")) // false
println("A" in list) // true
println("Z" in list) // false
}

You can also check the opposite to determine if the collection does not contain the element using the !in operator.

fun main() {
val letters = listOf("A", "B", "C")
println("A" !in list) // false
println("Z" !in list) // true
}

You can iterate over a list using a for-loop. Simply place a list on the right side of in.

fun main() {
val letters = listOf("A", "B", "C")
for (letter in letters) {
print(letter)
}
}

Mutable List

List is a type representing read-only lists. If you want to create a mutable list, use mutableListOf, and the result type is MutableList. With mutable lists, you can use methods like add or remove to add or remove a certain element.

fun main() {
val list = mutableListOf("A", "B")
list.add("C")
println(list) // [A, B, C]
list.remove("B")
println(list) // [A, C]
}

You can also change an element at a certain position using box brackets with index and assignment.

fun main() {
val list = mutableListOf("A", "B", "C")
list[1] = "Z"
println(list) // [A, Z, C]
}
Photo by Kelly Sikkema on Unsplash

SET

Sets are quite similar to lists; that’s why similar methods are used to operate on them. However, sets do not treat the order as seriously as lists. Some kinds of sets might not respect it. That is why you cannot get elements by index. Instead, sets require their elements to be unique. You will learn how they do that. But let’s start from the beginning, that is, creating a set.

You create a set using the setOf function, and then you specify the next values using arguments.

fun main() {
val set = setOf('A', 'B', 'C')
println(set) // [A, B, C]
}

The result type is Set<T>, where T is the type of elements in this set. Since the above code has a set with char values, the type is Set<Char>.

fun main() {
val set: Set<Char> = setOf('A', 'B', 'C')
println(set) // [A, B, C]
val ints: Set<Long> = setOf(1L, 2L, 3L)
println(ints) // [1, 2, 3]
}

The easiest way to add elements to sets is by using the plus sign. You can add a single element to a set, or you can add two sets together.

fun main() {
val set = setOf('A', 'B')
println(set + 'C') // [A, B, C]
println(set + setOf('C', 'D')) // [A, B, C, D]
println(setOf('Z') + set) // [Z, A, B]
}

You can always check the number of elements in a set using the size property.

fun main() {
val set = setOf('A', 'B', 'C')
println(set.size) // 3
}

To check if a set is empty, you can compare its size to 0, or you can use the isEmpty method.

fun main() {
val set = setOf('A', 'B', 'C')
println(set.size == 0) // false
println(set.isEmpty()) // false

val empty: Set<Int> = setOf()
println(empty.size == 0) // true
println(empty.isEmpty()) // true
}

Elements that are already in a set are not added; their addition is just ignored.

fun main() {
val set = setOf('A', 'B', 'C')
println(set + 'B') // [A, B, C]
println(set + setOf('B', 'D')) // [A, B, C, D]

val list = listOf('A', 'B', 'C')
println(list + 'B') // [A, B, C, B]
println(list + listOf('B', 'D')) // [A, B, C, B, D]
}

Also, if you duplicate arguments in the setOf function, the second argument will be ignored.

fun main() {
val set = setOf('A', 'B', 'A')
println(set) // [A, B]
}

Two elements are duplicated if they are equal, so if == between them returns true. Since regular classes are considered unique, they are never considered to be duplicates.

class User(val name: String)

fun main() {
val set = setOf(User("A"), User("A"))
println(set + User("A")) // [User@XXX, User@YYY, User@ZZZ]
}

However, data classes are equal when their all-constructor properties have the same values.

data class User(val name: String)

fun main() {
val set = setOf(User("A"), User("A"))
println(set + User("A")) // [User(name=A)]
}

You can check if a set contains a certain element. You can use the contains method or in operator. Both options return true if there is an element in the set equal to the element you are looking for, otherwise it returns false.

fun main() {
val letters = setOf('A', 'B', 'C')
println(set.contains('A')) // true
println(set.contains('Z')) // false
println('A' in set) // true
println('Z' in set) // false
}

You can also check the opposite to determine if the set does not contain the element, by using !in operator.

fun main() {
val letters = setOf("A", "B", "C")
println("A" !in list) // false
println("Z" !in list) // true
}

You can iterate over a set using a for-loop. Simply place a set on the right side of in.

fun main() {
val letters = setOf('A', 'B', 'C')
for (letter in letters) {
print(letter)
}
}

Mutable Set

Set is a type representing read-only sets. If you want to create a mutable set, use mutableSetOf, and the result type is MutableSet. With mutable sets, you can use methods like add or remove to add or remove a certain element.

fun main() {
val set = mutableSetOf('A', 'B')
set.add('C')
println(set) // [A, B, C]
set.remove('B')
println(set) // [A, C]
}
Photo by Dariusz Sankowski on Unsplash

MAP

Map represents an unordered collection of key-value pairs. Keys are unique and each of them maps to exactly one value. The values can have duplicates. Maps are useful for storing logical connections between objects, for example, an employee’s ID and their position.

You can create a map using the mapOf function and then use key-value pairs as arguments to specify key-value associations. For instance, you might define a map that associates countries with their capitals. Pairs can be defined using a constructor or using the to function.

fun main() {
val capitals = mapOf("USA" to "Washington", "Poland" to "Warsaw", "Ukraine" to "Kyiv")
// val capitals = mapOf(
// Pair("USA", "Washington"),
// Pair("Poland", "Warsaw"),
// Pair("Ukraine", "Kyiv")
// )
println(capitals) // {USA=Washington, Poland=Warsaw, Ukraine=Kyiv}
}

The result type is Map<K, V>, where K is the type of a key, and V is the type of the value. In the case of capitals, both keys and values are of type String, so the map type is Map<String, String>. However, it does not need to be the same type.

Consider a map with associations between letters and their positions in the English alphabet, as in the example below. Its type is Map<Char, Int>, because its keys are characters, and values are integers.

fun main() {
val capitals: Map<String, String> =
mapOf("USA" to "Washington", "Poland" to "Warsaw", "Ukraine" to "Kyiv")

println(capitals) // {USA=Washington, Poland=Warsaw, Ukraine=Kyiv}

val alphabet: Map<Char, Int> = mapOf('A' to 1, 'B' to 2, 'C' to 3)

println(alphabet) // {A=1, B=2, C=3}
}

To find a value by a key, use a box bracket with the key. For instance, to find a value for the key A in the alphabet map, use alphabet[‘A’]. The result is a nullable value type, so Int? in this case.

Why nullable? If the key you asked for is not in the map, then null will be returned.

fun main() {
val alphabet: Map<Char, Int> = mapOf('A' to 1, 'B' to 2, 'C' to 3)
val number: Int? = alphabet['A']
println(number) // 1
println(alphabet['B']) // 2
println(alphabet['&']) // null
}

Just like a regular list or a regular set, a regular map is read-only, so it does not have methods that would allow adding or removing elements. However, you can use plus sign to create a new map with new associations. If you add a pair into a map, the result is a map with a new association. If you add a new map, the result is a merge of those two maps.

fun main() {
val map1 = mapOf('A' to "Alex", 'B' to "Bob")
val map2 = map1 + ('C' to "Celina")
println(map1) // {A=Alex, B=Bob}
println(map2) // {A=Alex, B=Bob, C=Celina}
val map3 = mapOf('D' to "Daniel", 'E' to "Ellen")
val map4 = map2 + map3
println(map3) // {D=Daniel, E=Ellen}
println(map4) // {A=Alex, B=Bob, C=Celina, D=Daniel, E=Ellen}
}

Beware that duplicated keys are not allowed, so when you add a new association, it removes the old one.

fun main() {
val map1 = mapOf('A' to "Alex", 'B' to "Bob")
val map2 = map1 + ('B' to "Barbara")
println(map1) // {A=Alex, B=Bob}
println(map2) // {A=Alex, B=Barbara}
}

You can also remove certain keys from a map using the minus sign.

fun main() {
val map1 = mapOf('A' to "Alex", 'B' to "Bob")
val map2 = map1 - 'B'
println(map1) // {A=Alex, B=Bob}
println(map2) // {A=Alex}
}

You can check if your map contains a key using the in keyword.

fun main() {
val map = mapOf('A' to "Alex", 'B' to "Bob")
println('A' in map) // true
println('Z' in map) // false
}

You can check how many associations you have in a map using the size property.

fun main() {
val map = mapOf('A' to "Alex", 'B' to "Bob")
println(map.size) // 2
}

You can iterate over a map using a for-loop. You iterate over entries that contain key and value properties.

fun main() {
val map = mapOf('A' to "Alex", 'B' to "Bob")
for (entry in map) {
println("${entry.key} is for ${entry.value}")
}
}

// A is for Alex
// B is for Bob

You can also restructure an entry into two variables. Kotlin supports restructuring in a for-loop.

fun main() {
val map = mapOf('A' to "Alex", 'B' to "Bob")
for ((letter, name) in map) {
println("$letter is for $name")
}
}
// A is for Alex
// B is for Bob

Mutable Map

You can also create a mutable map using mapOf function.

The result type is MutableMap. You can add new associations to it using the put method or box bracket and assignment. You can also remove an association by key using the remove method.

fun main() {
val map: MutableMap<Char, String> = mutableMapOf('A' to "Alex", 'B' to "Bob")
map.put('C', "Celina")
map['D'] = "Daria"
println(map) // {A=Alex, B=Bob, D=Daria, C=Celina}
map.remove('B')
println(map) // {A=Alex, D=Daria, C=Celina}
}

İbrahim Can Erdoğan

LINKEDIN

YOUTUBE

UDEMY

GITHUB

--

--

ibrahimcanerdogan
ibrahimcanerdogan

Written by ibrahimcanerdogan

Hi, My name is Ibrahim, I am developing ebebek android app within Ebebek. I publish various articles in the field of programming and self-improvement.

No responses yet