Collections (List, Set, Map)
Kotlin is a modern, concise language with a rich, safe collections library — Lists for ordered data, Sets for unique values, and Maps for key-value pairs, each in read-only and mutable forms.
Learn Collections (List, Set, Map) in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll create and traverse all three collection types and know when to choose each.
What You'll Learn in This Lesson
1️⃣ Lists
A List stores items in order and allows duplicates. listOf(...) makes a read-only list; mutableListOf(...) makes one you can change. You access items by index and iterate with a for loop.
Notice how "banana" in fruits reads almost like English — the in operator checks membership.
2️⃣ Sets and Maps
A Set keeps only unique values. A Map stores key-value pairs, built with the to keyword. Both come in read-only ( setOf , mapOf ) and mutable forms.
Looping over a map with for ((name, age) in ages) destructures each entry into its key and value — clean and readable.
Your turn. Replace the TODO , then run and compare.
Mini-Challenge: A Tiny Inventory
Use a mutable map to track stock levels, update a quantity, and check availability.
Common Errors (and the fix)
- "Unresolved reference: add" — You called add on a read-only list. Use mutableListOf if you need to change it.
- IndexOutOfBoundsException — Accessing list[5] on a 3-item list crashes. Check size or use getOrNull(i) .
- Map lookup returns null — map[key] is nullable. Use ?: for a default, e.g. map["x"] ?: 0 .
- Expecting Set to keep order — A plain Set may not preserve insertion order. Use LinkedHashSet (the default from setOf actually does) if order matters.
Pro Tips
- 💡 Default to read-only: use listOf / mapOf unless you truly need to mutate.
- 💡 De-duplicate fast: myList.toSet().toList() removes duplicates while keeping order.
- 💡 Destructure entries: for ((k, v) in map) is cleaner than reading entry.key / entry.value .
📋 Quick Reference — Collections
Concept
Kotlin Syntax
Read-only list
listOf(1, 2, 3)
Mutable list
mutableListOf(1)
Set
setOf("a", "b")
Map
mapOf("k" to 1)
Look up safely
map["k"] ?: 0
Loop entries
for ((k, v) in map)
Frequently Asked Questions
🎉 Lesson Complete!
- ✅ listOf = read-only, mutableListOf = changeable
- ✅ Set holds unique values with fast membership
- ✅ Map stores key-value pairs built with to
- ✅ Map indexing is nullable — handle the missing key
- ✅ Destructure entries with for ((k, v) in map)
- ✅ Next lesson: Lambdas & Higher-Order Functions
Practice quiz
What is the difference between listOf and mutableListOf?
- listOf is faster
- mutableListOf cannot be iterated
- listOf is read-only; mutableListOf can add, remove, and replace
- They are identical
Answer: listOf is read-only; mutableListOf can add, remove, and replace. listOf gives a read-only list; mutableListOf can be modified.
What happens when you call add on a list created with listOf?
- It won't compile (unresolved reference: add)
- It appends silently
- It returns a new list
- It throws at runtime
Answer: It won't compile (unresolved reference: add). Read-only lists expose no add; use mutableListOf to modify.
What does a Set guarantee about its values?
- They stay sorted ascending
- They allow duplicates
- They are indexed by position
- They are unique; duplicates are dropped
Answer: They are unique; duplicates are dropped. A Set holds unique values and discards duplicates.
What does setOf(1, 2, 2, 3, 3, 3) contain?
Duplicates are dropped, leaving the unique values 1, 2, 3.
How is a Map built using the to keyword?
- mapOf("Ada" to 36) creates key-value pairs
- mapOf("Ada", 36)
- mapOf("Ada": 36)
- mapOf("Ada" => 36)
Answer: mapOf("Ada" to 36) creates key-value pairs. The to infix function creates Pair entries for the map.
What does indexing a map with map[key] return when the key is absent?
- An empty string
- Throws an exception
- null (the result type is nullable)
- Zero
Answer: null (the result type is nullable). Map indexing returns a nullable value; null means the key is missing.
What is an idiomatic way to read a map value with a fallback?
The Elvis operator ?: supplies a default when the value is null.
How do you loop over a map's entries with destructuring?
- for (entry of ages) { }
- ages.forEach(name, age)
- for name, age in ages
- for ((name, age) in ages) { }
Answer: for ((name, age) in ages) { }. Destructuring each entry into (key, value) reads cleanly.
Which collection should you prefer by default in Kotlin?
- Always mutable
- Read-only (listOf/mapOf) unless you truly need to mutate
- Always arrays
- Always Set
Answer: Read-only (listOf/mapOf) unless you truly need to mutate. Kotlin encourages read-only collections; they are safer and clearer.
When should you use a Set instead of a List?
- When you need indexed access
- When duplicates matter
- When you care about uniqueness and fast membership over order
- When order must be preserved by position
Answer: When you care about uniqueness and fast membership over order. Sets discard duplicates and offer fast contains checks.
Continue this course
- Previous: Default & Named Arguments
- Next: Lambdas & Higher-Order Functions