0
0
Kotlinprogramming~15 mins

For loop over collections in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - For loop over collections
What is it?
A for loop over collections in Kotlin lets you repeat actions for each item in a group, like a list or set. It helps you go through every element one by one without writing extra code to track positions. This makes working with groups of data simple and clear.
Why it matters
Without for loops over collections, you would have to manually access each item by its position, which is slow and error-prone. For loops save time and reduce mistakes when handling many items, like processing a list of names or numbers. They make programs easier to read and maintain.
Where it fits
Before learning for loops over collections, you should understand basic Kotlin syntax and what collections like lists and sets are. After this, you can learn about more advanced collection operations like map, filter, and fold to process data more powerfully.
Mental Model
Core Idea
A for loop over collections runs the same steps for each item in a group, one after another.
Think of it like...
It's like checking every book on a shelf one by one to find your favorite story.
Collection: [item1, item2, item3, ...]

for (item in collection) {
  // do something with item
}

Process flow:
┌───────────┐
│ collection│
└─────┬─────┘
      │
      ▼
┌───────────┐
│ item1     │
│ process   │
└─────┬─────┘
      │
      ▼
┌───────────┐
│ item2     │
│ process   │
└─────┬─────┘
      │
     ...
      │
      ▼
┌───────────┐
│ itemN     │
│ process   │
└───────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding collections in Kotlin
🤔
Concept: Learn what collections like lists and sets are and how they store multiple items.
In Kotlin, collections are groups of items stored together. For example, a list holds items in order, and a set holds unique items without order. You can create a list like this: val fruits = listOf("apple", "banana", "cherry") This list has three fruit names stored inside.
Result
You have a group of items stored in a variable called fruits.
Knowing what collections are is essential because for loops work by going through these groups one item at a time.
2
FoundationBasic for loop syntax in Kotlin
🤔
Concept: Learn the simple structure of a for loop to repeat actions multiple times.
A for loop in Kotlin looks like this: for (i in 1..3) { println(i) } This prints numbers 1, 2, and 3. The loop runs once for each number in the range 1 to 3.
Result
Output: 1 2 3
Understanding the basic for loop helps you see how Kotlin repeats code, which is the foundation for looping over collections.
3
IntermediateFor loop over a list collection
🤔Before reading on: do you think the loop variable holds the item itself or its position index? Commit to your answer.
Concept: Learn how to loop through each item directly in a list using for loop syntax.
You can loop over a list by writing: val fruits = listOf("apple", "banana", "cherry") for (fruit in fruits) { println(fruit) } This prints each fruit name one by one.
Result
Output: apple banana cherry
Knowing that the loop variable holds the actual item, not the index, makes your code simpler and clearer.
4
IntermediateLooping with index and value pairs
🤔Before reading on: can you get both the position and the item in a for loop easily? Commit to yes or no.
Concept: Learn how to access both the index and the item during a loop over a collection.
Use the withIndex() function to get index and value: val fruits = listOf("apple", "banana", "cherry") for ((index, fruit) in fruits.withIndex()) { println("Item $index is $fruit") } This prints each fruit with its position.
Result
Output: Item 0 is apple Item 1 is banana Item 2 is cherry
Accessing both index and value helps when you need to know the position of items while looping.
5
IntermediateFor loop over other collections like sets
🤔
Concept: Learn that for loops work similarly on other collections like sets, which have no order.
A set holds unique items without order: val numbers = setOf(10, 20, 30) for (num in numbers) { println(num) } The loop prints each number, but order is not guaranteed.
Result
Output (order may vary): 10 20 30
Understanding that for loops work on any collection type broadens your ability to process different data structures.
6
AdvancedUsing for loops with mutable collections
🤔Before reading on: do you think you can change items inside a for loop directly? Commit to yes or no.
Concept: Learn how to loop over mutable collections and modify items safely.
Mutable collections like MutableList allow changes: val numbers = mutableListOf(1, 2, 3) for (i in numbers.indices) { numbers[i] = numbers[i] * 2 } println(numbers) This doubles each number in the list.
Result
Output: [2, 4, 6]
Knowing you must use indices to modify items prevents errors and shows how for loops can update collections.
7
ExpertPerformance and pitfalls of for loops on collections
🤔Before reading on: do you think all for loops over collections have the same speed? Commit to yes or no.
Concept: Understand how different collections and loop styles affect performance and when to avoid certain loops.
For example, looping over a LinkedList by index is slow because each index access scans from start: val linkedList = java.util.LinkedList(listOf(1,2,3)) for (i in 0 until linkedList.size) { println(linkedList[i]) // slow for LinkedList } Better to use for (item in linkedList) for speed. Also, modifying collections while looping can cause errors.
Result
Output: 1 2 3 But the first loop is inefficient on LinkedList.
Understanding collection internals helps you write efficient loops and avoid bugs with concurrent modification.
Under the Hood
When you write a for loop over a collection in Kotlin, the compiler uses the collection's iterator() function to get an iterator object. This iterator moves step-by-step through the collection, giving one item at a time. The loop calls hasNext() to check if more items exist and next() to get the current item. This hides the complexity of tracking positions and lets you focus on the item itself.
Why designed this way?
This design follows the iterator pattern common in many languages, making loops simple and consistent across collection types. It avoids exposing internal details like indexes, which may not exist in all collections (like sets). This approach also allows Kotlin to support many collection types uniformly.
for (item in collection) {
  // body
}

  ↓

collection.iterator() ──▶ Iterator object
          │
          ├─ hasNext()?
          │      ├─ yes: next() returns item
          │      └─ no: loop ends
          ↓
      loop body runs with item
Myth Busters - 3 Common Misconceptions
Quick: Does the for loop variable hold the index number or the actual item? Commit to your answer.
Common Belief:The loop variable in a for loop over a collection holds the index number of the item.
Tap to reveal reality
Reality:The loop variable holds the actual item, not the index. To get the index, you must use withIndex() or loop over indices explicitly.
Why it matters:Assuming the variable is an index leads to bugs where you treat items as numbers or positions incorrectly, causing crashes or wrong results.
Quick: Can you safely modify a collection while looping over it with a for loop? Commit to yes or no.
Common Belief:You can change items or add/remove elements in a collection while looping over it with a for loop without problems.
Tap to reveal reality
Reality:Modifying a collection during a for loop can cause runtime errors or unexpected behavior, especially if you add or remove items. Safe modification requires special care or different approaches.
Why it matters:Ignoring this can crash your program or corrupt data, making bugs hard to find.
Quick: Is looping over a LinkedList by index as fast as looping over an ArrayList? Commit to yes or no.
Common Belief:Looping over any list by index is equally fast regardless of the list type.
Tap to reveal reality
Reality:Looping by index on a LinkedList is slow because each index access scans from the start, unlike ArrayList which has fast random access.
Why it matters:Not knowing this can cause performance problems in real applications, making your code slow and inefficient.
Expert Zone
1
Using for loops with sequences differs because sequences are lazy and compute items on demand, which affects performance and side effects.
2
The iterator used in for loops can be customized by implementing operator functions, enabling for loops on your own classes.
3
Kotlin's for loop syntax desugars to iterator calls, but you can override iterator() to change loop behavior, a powerful but rarely used feature.
When NOT to use
Avoid for loops when you need complex transformations or filtering; instead, use Kotlin's collection functions like map, filter, or forEach for clearer and more expressive code.
Production Patterns
In production, for loops are often used for simple iteration, but functional style with collection operators is preferred for readability and chaining. For loops remain essential when you need explicit control over iteration or side effects.
Connections
Iterator Pattern
For loops in Kotlin build directly on the iterator pattern from software design.
Understanding the iterator pattern explains why for loops work uniformly on many collection types and how they hide complexity.
Functional Programming
For loops are a basic form of iteration, while functional programming uses higher-order functions to process collections.
Knowing for loops helps you appreciate the power and expressiveness of functional collection operations like map and filter.
Assembly Language Loops
Both Kotlin for loops and assembly loops repeat instructions, but Kotlin abstracts away low-level details.
Seeing loops at different abstraction levels shows how programming languages evolve to make repetitive tasks easier and less error-prone.
Common Pitfalls
#1Trying to modify a list item directly inside a for loop over the collection.
Wrong approach:val numbers = listOf(1, 2, 3) for (num in numbers) { num = num * 2 // error: val cannot be reassigned }
Correct approach:val numbers = mutableListOf(1, 2, 3) for (i in numbers.indices) { numbers[i] = numbers[i] * 2 }
Root cause:Misunderstanding that the loop variable is a copy of the item, not a reference you can change.
#2Using for loop with index on a LinkedList causing slow performance.
Wrong approach:val linkedList = java.util.LinkedList(listOf(1, 2, 3)) for (i in 0 until linkedList.size) { println(linkedList[i]) // slow }
Correct approach:val linkedList = java.util.LinkedList(listOf(1, 2, 3)) for (item in linkedList) { println(item) // fast }
Root cause:Not knowing that LinkedList does not support fast random access by index.
#3Assuming the loop variable holds the index instead of the item.
Wrong approach:val fruits = listOf("apple", "banana") for (fruit in fruits) { println("Index: $fruit") // prints fruit, not index }
Correct approach:val fruits = listOf("apple", "banana") for ((index, fruit) in fruits.withIndex()) { println("Index: $index, Fruit: $fruit") }
Root cause:Confusing the loop variable's role and not using withIndex() when index is needed.
Key Takeaways
For loops over collections let you process each item in a group easily and clearly without manual indexing.
The loop variable holds the actual item, not its position, unless you explicitly ask for the index with withIndex().
For loops use iterators under the hood, which work uniformly across many collection types like lists and sets.
Modifying collections during a for loop requires care; use indices or other safe methods to avoid errors.
Understanding collection types and their performance characteristics helps you write efficient and bug-free loops.