0
0
Kotlinprogramming~15 mins

Set creation (setOf, mutableSetOf) in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - Set creation (setOf, mutableSetOf)
What is it?
In Kotlin, sets are collections that hold unique elements without any specific order. You can create sets using setOf for read-only sets and mutableSetOf for sets that you can change by adding or removing elements. These functions help you quickly make sets to store data where duplicates are not allowed.
Why it matters
Sets solve the problem of storing unique items efficiently, which is common in many programs like managing user IDs or tags. Without sets, you might accidentally store duplicates or write extra code to check for uniqueness, making your program slower and more complex.
Where it fits
Before learning set creation, you should understand basic collections like lists and arrays. After mastering sets, you can explore more advanced collection operations, such as filtering, mapping, and working with other collection types like maps.
Mental Model
Core Idea
A set is like a bag that only lets you keep one of each kind of item, and Kotlin provides easy ways to create fixed or changeable bags.
Think of it like...
Imagine a basket where you put fruits, but you never want two apples or two bananas. If you try to add a fruit that's already inside, the basket ignores it. You can have a basket that you can't change (read-only) or one where you can add or remove fruits anytime (mutable).
Set Creation in Kotlin

┌───────────────┐       ┌───────────────────┐
│  setOf(...)   │──────▶│ Read-only Set      │
│ (immutable)   │       │ No add/remove      │
└───────────────┘       └───────────────────┘

┌─────────────────┐     ┌────────────────────┐
│ mutableSetOf(...)│────▶│ Mutable Set         │
│ (mutable)        │     │ Can add/remove      │
└─────────────────┘     └────────────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Sets and Uniqueness
🤔
Concept: Sets store unique elements without duplicates.
A set is a collection that does not allow duplicate values. For example, if you try to add the number 5 twice, the set will only keep one 5. This is different from a list, which can have duplicates.
Result
You get a collection where each element appears only once.
Understanding that sets automatically prevent duplicates helps you avoid manual checks and errors in your code.
2
FoundationCreating Read-Only Sets with setOf
🤔
Concept: Use setOf to create a fixed set that cannot be changed after creation.
val fruits = setOf("apple", "banana", "apple") println(fruits) // Output: [apple, banana] This creates a set with two unique fruits. Trying to add or remove elements later will cause an error because it's read-only.
Result
[apple, banana]
Knowing that setOf creates an immutable set helps you write safer code when you don't want the collection to change.
3
IntermediateCreating Mutable Sets with mutableSetOf
🤔
Concept: Use mutableSetOf to create a set you can change by adding or removing elements.
val numbers = mutableSetOf(1, 2, 3) numbers.add(4) numbers.remove(2) println(numbers) // Output: [1, 3, 4] You can add or remove elements anytime, but duplicates are still not allowed.
Result
[1, 3, 4]
Understanding mutable sets lets you manage collections that need to change over time while still preventing duplicates.
4
IntermediateSet Behavior with Duplicate Elements
🤔Before reading on: If you add a duplicate element to a mutable set, do you think it will add it again or ignore it? Commit to your answer.
Concept: Sets ignore duplicates even when mutable.
val letters = mutableSetOf('a', 'b') letters.add('a') println(letters) // Output: [a, b] Adding 'a' again does not change the set because 'a' is already present.
Result
[a, b]
Knowing that sets never allow duplicates, even when mutable, prevents bugs where you expect duplicates to appear.
5
IntermediateEmpty Sets and Type Inference
🤔
Concept: Creating empty sets requires specifying the type to avoid errors.
val emptySet = setOf() val emptyMutableSet = mutableSetOf() Without specifying the type, Kotlin cannot guess what kind of elements the set will hold.
Result
Empty sets ready to hold elements of the specified type.
Understanding type inference with empty sets helps avoid confusing compiler errors.
6
AdvancedPerformance Characteristics of Sets
🤔Before reading on: Do you think sets check for duplicates by scanning all elements or using a faster method? Commit to your answer.
Concept: Sets use hashing to quickly check for duplicates and membership.
Kotlin's sets are usually backed by hash tables, which means checking if an element exists or adding a new one happens very fast, even with many elements. This is much faster than scanning a list.
Result
Fast operations for adding, removing, and checking elements.
Knowing the underlying performance helps you choose sets for large data where speed matters.
7
ExpertImmutable vs Mutable Set Implementations
🤔Before reading on: Do you think setOf and mutableSetOf create the same kind of set internally? Commit to your answer.
Concept: Kotlin uses different internal classes for immutable and mutable sets with different behaviors and optimizations.
setOf creates an instance of an immutable set class that does not allow modification and can optimize memory usage. mutableSetOf creates a HashSet instance that supports changes. Understanding this helps when you need thread safety or want to optimize memory.
Result
Different internal implementations affect behavior and performance.
Knowing the internal differences helps you write more efficient and safe Kotlin code, especially in multi-threaded or memory-sensitive contexts.
Under the Hood
Kotlin's setOf creates an immutable set backed by a specialized internal class that stores elements without duplicates and disallows modification. mutableSetOf creates a HashSet, which uses a hash table to store elements. Each element's hash code determines its position, allowing fast lookup, insertion, and removal. When adding an element, the set checks if the hash code already exists to prevent duplicates.
Why designed this way?
Immutable sets provide safety by preventing accidental changes, which is important in functional programming and multi-threaded environments. Mutable sets offer flexibility when collections need to change. Using hash tables balances speed and memory use, making sets efficient for common operations.
Set Creation Mechanism

┌───────────────┐          ┌───────────────┐
│  setOf(...)   │─────────▶│ ImmutableSet  │
│ (read-only)   │          │ (no changes)  │
└───────────────┘          └───────────────┘

┌─────────────────┐        ┌───────────────┐
│ mutableSetOf(...)│───────▶│ HashSet       │
│ (mutable)        │        │ (hash table)  │
└─────────────────┘        └───────────────┘

HashSet internals:
┌───────────────┐
│ Element Hash  │
│ Table Bucket  │
│ Collision     │
│ Resolution   │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does setOf create a set you can add elements to later? Commit yes or no.
Common Belief:setOf creates a set that you can add or remove elements from anytime.
Tap to reveal reality
Reality:setOf creates an immutable set that cannot be changed after creation.
Why it matters:Trying to modify a setOf set causes runtime errors or compilation failures, leading to bugs and crashes.
Quick: If you add a duplicate element to a mutableSetOf, does it add it again? Commit yes or no.
Common Belief:mutableSetOf allows duplicates because it's mutable.
Tap to reveal reality
Reality:mutableSetOf still prevents duplicates; adding an existing element does nothing.
Why it matters:Expecting duplicates can cause logic errors when counting or processing elements.
Quick: Is the order of elements in a set guaranteed? Commit yes or no.
Common Belief:Sets keep elements in the order you add them.
Tap to reveal reality
Reality:Sets do not guarantee any order; elements may appear in any order when iterated.
Why it matters:Relying on order in sets can cause unpredictable behavior and bugs.
Quick: Does creating an empty set without specifying type always work? Commit yes or no.
Common Belief:You can create an empty set without specifying the element type and Kotlin will figure it out.
Tap to reveal reality
Reality:Kotlin requires explicit type for empty sets to know what kind of elements it will hold.
Why it matters:Not specifying type causes compiler errors, blocking progress and confusing beginners.
Expert Zone
1
Immutable sets created by setOf can share internal storage for small sets, saving memory.
2
Mutable sets use hash codes, so custom objects must properly override hashCode and equals to behave correctly in sets.
3
The iteration order of sets is not guaranteed but can be stable in some implementations; relying on this is risky.
When NOT to use
Avoid sets when you need to preserve insertion order; use LinkedHashSet instead. For large datasets requiring sorted order, use sortedSetOf or TreeSet. If you need to store duplicates, use lists instead.
Production Patterns
In production, sets are used for fast membership checks, like filtering unique user IDs or tags. Mutable sets manage dynamic collections like active sessions. Immutable sets help in multi-threaded code to avoid synchronization issues.
Connections
Hash Tables
Sets are built on hash tables to provide fast lookup and uniqueness.
Understanding hash tables explains why sets are efficient and why proper hashCode implementations matter.
Functional Programming Immutability
Immutable sets align with functional programming principles of no side effects.
Knowing immutability in sets helps grasp safer code design and concurrency benefits.
Database Unique Constraints
Sets enforce uniqueness like unique constraints in databases.
Recognizing this connection helps understand how sets prevent duplicates similarly to database rules.
Common Pitfalls
#1Trying to add elements to a set created with setOf.
Wrong approach:val mySet = setOf(1, 2, 3) mySet.add(4) // Error: Unresolved reference: add
Correct approach:val mySet = mutableSetOf(1, 2, 3) mySet.add(4) // Works fine
Root cause:Misunderstanding that setOf creates immutable sets that do not support modification.
#2Expecting duplicates to be stored in a mutable set.
Wrong approach:val mySet = mutableSetOf("a", "b") mySet.add("a") println(mySet) // Expecting [a, b, a]
Correct approach:val mySet = mutableSetOf("a", "b") mySet.add("a") println(mySet) // Actual output: [a, b]
Root cause:Not realizing sets always prevent duplicates regardless of mutability.
#3Creating an empty set without specifying type and expecting it to compile.
Wrong approach:val emptySet = setOf() // Error: Type inference failed
Correct approach:val emptySet = setOf() // Compiles successfully
Root cause:Kotlin cannot infer the element type for an empty set without explicit type.
Key Takeaways
Kotlin provides setOf for immutable sets and mutableSetOf for sets you can change.
Sets automatically prevent duplicate elements, making them ideal for unique collections.
Mutable sets allow adding and removing elements, but still never store duplicates.
Immutable sets are safer for fixed data and multi-threaded code, while mutable sets offer flexibility.
Understanding how sets use hashing explains their fast performance and the importance of proper element equality.