Skip to content

Loops

Overview

Kotlin provides multiple loop structures for repeatedly executing code blocks, including for loops, while loops, and do-while loops. Kotlin's loop statements are powerful, supporting ranges, collection iteration, and various control flow operations.

for Loops

Basic for Loop

kotlin
fun main() {
    // Iterate over a range
    println("Basic for loop:")
    for (i in 1..5) {
        println("Number: $i")
    }
    
    // Iterate over character range
    println("\nCharacter range:")
    for (c in 'a'..'e') {
        println("Character: $c")
    }
    
    // Using until (exclusive of end value)
    println("\nuntil loop:")
    for (i in 1 until 5) {
        println("Number: $i")
    }
    
    // Descending loop
    println("\nDescending loop:")
    for (i in 5 downTo 1) {
        println("Countdown: $i")
    }
    
    // Specifying step
    println("\nWith step:")
    for (i in 1..10 step 2) {
        println("Odd: $i")
    }
    
    for (i in 10 downTo 1 step 3) {
        println("Descending step 3: $i")
    }
}

Iterating Collections

kotlin
fun main() {
    val fruits = listOf("Apple", "Banana", "Orange", "Grape")
    val numbers = arrayOf(1, 2, 3, 4, 5)
    val map = mapOf("a" to 1, "b" to 2, "c" to 3)
    
    // Iterate over list
    println("Iterate over list:")
    for (fruit in fruits) {
        println("Fruit: $fruit")
    }
    
    // Iterate over array
    println("\nIterate over array:")
    for (number in numbers) {
        println("Number: $number")
    }
    
    // Iterate with index
    println("\nIterate with index:")
    for ((index, fruit) in fruits.withIndex()) {
        println("$index: $fruit")
    }
    
    // Iterate over map
    println("\nIterate over map:")
    for ((key, value) in map) {
        println("$key -> $value")
    }
    
    // Iterate over keys only
    println("\nIterate over keys:")
    for (key in map.keys) {
        println("Key: $key")
    }
    
    // Iterate over values only
    println("\nIterate over values:")
    for (value in map.values) {
        println("Value: $value")
    }
}

Nested Loops

kotlin
fun main() {
    // Print multiplication table
    println("Multiplication table:")
    for (i in 1..9) {
        for (j in 1..i) {
            print("${j}×${i}=${i*j}\t")
        }
        println()
    }
    
    // 2D array iteration
    val matrix = arrayOf(
        arrayOf(1, 2, 3),
        arrayOf(4, 5, 6),
        arrayOf(7, 8, 9)
    )
    
    println("\nMatrix iteration:")
    for (row in matrix) {
        for (element in row) {
            print("$element\t")
        }
        println()
    }
    
    // 2D iteration with index
    println("\nMatrix iteration with index:")
    for ((rowIndex, row) in matrix.withIndex()) {
        for ((colIndex, element) in row.withIndex()) {
            println("matrix[$rowIndex][$colIndex] = $element")
        }
    }
}

while Loops

Basic while Loop

kotlin
fun main() {
    // Basic while loop
    var count = 1
    println("while loop:")
    while (count <= 5) {
        println("Count: $count")
        count++
    }
    
    // Complex condition while loop
    var number = 1
    println("\nPowers of 2:")
    while (number <= 100) {
        println("2^${kotlin.math.log2(number.toDouble()).toInt()} = $number")
        number *= 2
    }
    
    // User input simulation
    val inputs = listOf("hello", "world", "quit", "more")
    var inputIndex = 0
    
    println("\nSimulated user input:")
    while (inputIndex < inputs.size) {
        val input = inputs[inputIndex]
        println("Input: $input")
        
        if (input == "quit") {
            println("Exiting program")
            break
        }
        
        inputIndex++
    }
}

do-while Loop

kotlin
fun main() {
    // do-while loop (executes at least once)
    var attempts = 0
    val maxAttempts = 3
    
    println("do-while loop example:")
    do {
        attempts++
        println("Attempt $attempts")
        
        // Simulate some condition check
        val success = attempts >= 2  // Success on 2nd attempt
        
        if (success) {
            println("Operation successful!")
            break
        } else {
            println("Operation failed, retrying...")
        }
        
    } while (attempts < maxAttempts)
    
    if (attempts >= maxAttempts) {
        println("Maximum attempts reached")
    }
    
    // Menu system example
    val menuOptions = listOf("1. View", "2. Add", "3. Delete", "0. Exit")
    val userChoices = listOf("1", "2", "invalid", "0")  // Simulated user choices
    var choiceIndex = 0
    
    println("\nMenu system:")
    do {
        println("\nPlease select an operation:")
        menuOptions.forEach { println(it) }
        
        val choice = if (choiceIndex < userChoices.size) {
            userChoices[choiceIndex++]
        } else {
            "0"
        }
        
        println("Your choice: $choice")
        
        when (choice) {
            "1" -> println("Executing view operation")
            "2" -> println("Executing add operation")
            "3" -> println("Executing delete operation")
            "0" -> println("Exiting system")
            else -> println("Invalid choice, please try again")
        }
        
    } while (choice != "0")
}

Loop Control Statements

break and continue

kotlin
fun main() {
    // break example
    println("break example - find first even number:")
    for (i in 1..10) {
        if (i % 2 == 0) {
            println("Found first even number: $i")
            break
        }
        println("Checking: $i")
    }
    
    // continue example
    println("\ncontinue example - skip even numbers:")
    for (i in 1..10) {
        if (i % 2 == 0) {
            continue  // Skip even numbers
        }
        println("Odd: $i")
    }
    
    // break and continue in nested loops
    println("\nControl in nested loops:")
    for (i in 1..3) {
        println("Outer loop: $i")
        for (j in 1..5) {
            if (j == 3) {
                println("  Skipping inner $j")
                continue
            }
            if (j == 4) {
                println("  Inner loop ended early")
                break
            }
            println("  Inner loop: $j")
        }
    }
}

Labels and Jumps

kotlin
fun main() {
    // Using labels to control nested loops
    println("Label jump example:")
    
    outer@ for (i in 1..3) {
        inner@ for (j in 1..3) {
            if (i == 2 && j == 2) {
                println("Breaking outer loop at ($i, $j)")
                break@outer  // Break out of outer loop
            }
            println("($i, $j)")
        }
    }
    
    println("\nLabel continue example:")
    outer@ for (i in 1..3) {
        for (j in 1..3) {
            if (j == 2) {
                println("Continue outer loop at ($i, $j)")
                continue@outer  // Continue to next iteration of outer loop
            }
            println("($i, $j)")
        }
    }
}

Functional Loop Operations

forEach and Other Higher-Order Functions

kotlin
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    // forEach
    println("forEach:")
    numbers.forEach { number ->
        println("Number: $number")
    }
    
    // forEachIndexed
    println("\nforEachIndexed:")
    numbers.forEachIndexed { index, number ->
        println("Index $index: $number")
    }
    
    // map - transform each element
    println("\nmap - square:")
    val squares = numbers.map { it * it }
    println(squares)
    
    // filter - filter elements
    println("\nfilter - even numbers:")
    val evens = numbers.filter { it % 2 == 0 }
    println(evens)
    
    // Chain operations
    println("\nChained operations - squares of even numbers:")
    val evenSquares = numbers
        .filter { it % 2 == 0 }
        .map { it * it }
    println(evenSquares)
    
    // reduce - aggregation
    println("\nreduce - sum:")
    val sum = numbers.reduce { acc, number -> acc + number }
    println("Total: $sum")
    
    // fold - aggregation with initial value
    println("\nfold - product with initial value:")
    val product = numbers.fold(1) { acc, number -> acc * number }
    println("Product: $product")
}

repeat Function

kotlin
fun main() {
    // repeat function
    println("repeat function:")
    repeat(5) { index ->
        println("Repeat $index times")
    }
    
    // Practical application: Retry mechanism
    fun simulateNetworkCall(): Boolean {
        return kotlin.random.Random.nextBoolean()
    }
    
    println("\nRetry mechanism example:")
    var success = false
    repeat(3) { attempt ->
        println("Attempt ${attempt + 1} network request")
        success = simulateNetworkCall()
        if (success) {
            println("Request successful!")
            return@repeat  // Exit repeat early
        } else {
            println("Request failed")
        }
    }
    
    if (!success) {
        println("All retries failed")
    }
}

Practical Examples

Data Processing

kotlin
data class Student(val name: String, val age: Int, val grades: List<Int>)

fun main() {
    val students = listOf(
        Student("Alice", 20, listOf(85, 92, 78, 96)),
        Student("Bob", 19, listOf(76, 84, 88, 79)),
        Student("Charlie", 21, listOf(95, 89, 92, 98)),
        Student("Diana", 20, listOf(82, 87, 85, 90))
    )
    
    println("Student grade analysis:")
    
    // Calculate each student's average grade
    for (student in students) {
        val average = student.grades.average()
        val grade = when {
            average >= 90 -> "A"
            average >= 80 -> "B"
            average >= 70 -> "C"
            else -> "D"
        }
        println("${student.name} (age ${student.age}): Average %.1f, Grade $grade".format(average))
    }
    
    // Find top student
    var topStudent: Student? = null
    var highestAverage = 0.0
    
    for (student in students) {
        val average = student.grades.average()
        if (average > highestAverage) {
            highestAverage = average
            topStudent = student
        }
    }
    
    println("\nTop student: ${topStudent?.name}, Average: %.1f".format(highestAverage))
    
    // Count students by grade
    val gradeCount = mutableMapOf("A" to 0, "B" to 0, "C" to 0, "D" to 0)
    
    for (student in students) {
        val average = student.grades.average()
        val grade = when {
            average >= 90 -> "A"
            average >= 80 -> "B"
            average >= 70 -> "C"
            else -> "D"
        }
        gradeCount[grade] = gradeCount[grade]!! + 1
    }
    
    println("\nGrade statistics:")
    for ((grade, count) in gradeCount) {
        println("Grade $grade: $count students")
    }
}

Game Development Example

kotlin
class GameBoard(val size: Int) {
    private val board = Array(size) { Array(size) { '.' } }
    
    fun placeSymbol(row: Int, col: Int, symbol: Char): Boolean {
        return if (isValidPosition(row, col) && board[row][col] == '.') {
            board[row][col] = symbol
            true
        } else {
            false
        }
    }
    
    private fun isValidPosition(row: Int, col: Int): Boolean {
        return row in 0 until size && col in 0 until size
    }
    
    fun display() {
        println("  " + (0 until size).joinToString(" "))
        for ((rowIndex, row) in board.withIndex()) {
            print("$rowIndex ")
            for (cell in row) {
                print("$cell ")
            }
            println()
        }
    }
    
    fun checkWin(symbol: Char): Boolean {
        // Check rows
        for (row in board) {
            var count = 0
            for (cell in row) {
                if (cell == symbol) count++ else count = 0
                if (count >= 3) return true
            }
        }
        
        // Check columns
        for (col in 0 until size) {
            var count = 0
            for (row in 0 until size) {
                if (board[row][col] == symbol) count++ else count = 0
                if (count >= 3) return true
            }
        }
        
        // Check diagonals
        for (startRow in 0 until size - 2) {
            for (startCol in 0 until size - 2) {
                var count = 0
                for (i in 0 until 3) {
                    if (board[startRow + i][startCol + i] == symbol) {
                        count++
                    } else {
                        break
                    }
                }
                if (count >= 3) return true
            }
        }
        
        return false
    }
}

fun main() {
    val game = GameBoard(5)
    val moves = listOf(
        Triple(0, 0, 'X'), Triple(0, 1, 'O'),
        Triple(1, 1, 'X'), Triple(1, 2, 'O'),
        Triple(2, 2, 'X'), Triple(2, 3, 'O')
    )
    
    println("Tic-tac-toe demo:")
    game.display()
    
    for ((row, col, symbol) in moves) {
        println("\nPlayer $symbol places at ($row, $col)")
        if (game.placeSymbol(row, col, symbol)) {
            game.display()
            if (game.checkWin(symbol)) {
                println("Player $symbol wins!")
                break
            }
        } else {
            println("Invalid move!")
        }
    }
}

Algorithm Implementation

kotlin
// Bubble sort
fun bubbleSort(arr: IntArray) {
    val n = arr.size
    for (i in 0 until n - 1) {
        var swapped = false
        for (j in 0 until n - i - 1) {
            if (arr[j] > arr[j + 1]) {
                // Swap elements
                val temp = arr[j]
                arr[j] = arr[j + 1]
                arr[j + 1] = temp
                swapped = true
            }
        }
        // If no swaps, already sorted
        if (!swapped) break
    }
}

// Binary search
fun binarySearch(arr: IntArray, target: Int): Int {
    var left = 0
    var right = arr.size - 1
    
    while (left <= right) {
        val mid = left + (right - left) / 2
        
        when {
            arr[mid] == target -> return mid
            arr[mid] < target -> left = mid + 1
            else -> right = mid - 1
        }
    }
    
    return -1  // Not found
}

// Fibonacci sequence
fun fibonacci(n: Int): Long {
    if (n <= 1) return n.toLong()
    
    var prev = 0L
    var curr = 1L
    
    for (i in 2..n) {
        val next = prev + curr
        prev = curr
        curr = next
    }
    
    return curr
}

fun main() {
    // Sorting demo
    val numbers = intArrayOf(64, 34, 25, 12, 22, 11, 90)
    println("Before sorting: ${numbers.contentToString()}")
    bubbleSort(numbers)
    println("After sorting: ${numbers.contentToString()}")
    
    // Binary search demo
    val target = 25
    val index = binarySearch(numbers, target)
    if (index != -1) {
        println("Found $target at index $index")
    } else {
        println("$target not found")
    }
    
    // Fibonacci sequence
    println("\nFirst 10 Fibonacci numbers:")
    for (i in 0..9) {
        print("${fibonacci(i)} ")
    }
    println()
}

Performance Optimization

Loop Optimization Tips

kotlin
fun main() {
    val largeList = (1..1000000).toList()
    
    // 1. Use appropriate loop type
    // For simple iteration, forEach is often faster than traditional for loop
    
    // 2. Avoid creating unnecessary objects in loops
    // Bad practice
    fun badExample() {
        for (i in largeList) {
            val result = "Number: $i"  // Creates new string each time
            // Process result...
        }
    }
    
    // Good practice
    fun goodExample() {
        val sb = StringBuilder()
        for (i in largeList) {
            sb.clear()
            sb.append("Number: ").append(i)
            val result = sb.toString()
            // Process result...
        }
    }
    
    // 3. Use sequences for lazy evaluation
    val result = largeList.asSequence()
        .filter { it % 2 == 0 }
        .map { it * it }
        .take(10)
        .toList()
    
    println("First 10 squares of even numbers: $result")
    
    // 4. Exit loops early
    fun findFirst(predicate: (Int) -> Boolean): Int? {
        for (item in largeList) {
            if (predicate(item)) {
                return item  // Return immediately when found
            }
        }
        return null
    }
    
    val firstLargeNumber = findFirst { it > 500000 }
    println("First number greater than 500000: $firstLargeNumber")
}

Best Practices

1. Choose the Right Loop Type

kotlin
fun main() {
    val items = listOf("a", "b", "c", "d", "e")
    
    // Simple iteration: use forEach
    items.forEach { println(it) }
    
    // Need index: use forEachIndexed or withIndex
    items.forEachIndexed { index, item ->
        println("$index: $item")
    }
    
    // Need transformation: use map
    val upperCase = items.map { it.uppercase() }
    
    // Need filtering: use filter
    val filtered = items.filter { it != "c" }
    
    // Complex logic: use traditional for loop
    for (i in items.indices) {
        if (i > 0 && items[i] == items[i-1]) {
            // Complex adjacent element comparison logic
        }
    }
}

2. Avoid Deep Nesting

kotlin
// Bad practice: Too deep nesting
fun badNestedLoops(matrix: Array<Array<Int>>) {
    for (i in matrix.indices) {
        for (j in matrix[i].indices) {
            for (k in 0..10) {
                if (matrix[i][j] == k) {
                    for (l in 0..5) {
                        // Too deep, hard to understand
                    }
                }
            }
        }
    }
}

// Good practice: Extract functions
fun goodNestedLoops(matrix: Array<Array<Int>>) {
    for (i in matrix.indices) {
        for (j in matrix[i].indices) {
            processCell(matrix[i][j])
        }
    }
}

fun processCell(value: Int) {
    for (k in 0..10) {
        if (value == k) {
            performOperation(k)
        }
    }
}

fun performOperation(k: Int) {
    for (l in 0..5) {
        // Specific operation
    }
}

Next Steps

After mastering loop statements, let's learn about function definition and usage in Kotlin, including higher-order functions and lambda expressions.

Next Chapter: Functions

Exercises

  1. Write a program to generate a multiplication table of specified size
  2. Implement a simple number guessing game using loops to handle user input
  3. Create a function to calculate statistics for all elements in an array (max, min, average, etc.)
  4. Implement selection sort algorithm and compare its performance with bubble sort
  5. Write a program to generate the first n rows of Pascal's triangle

Content is for learning and research only.