Popular Searches
Popular Course Categories
Popular Courses

Implementing Loops and Iteration Techniques

Implementing Loops and Iteration Techniques

Kotlin Programming Fundamentals for Android

Implementing Loops and Iteration Techniques in Kotlin

Course: Android App Development

Topic: Implementing Loops and Iteration Techniques

Course Link: Android App Development Course

Demo Link: Register for Course Demo

Website: JustAcademy


1. Introduction to Loops in Kotlin

Loops are fundamental programming structures that allow developers to execute a block of code repeatedly. Instead of writing the same statements multiple times, a loop performs repetitive tasks based on a condition or a collection of elements.

In Android app development, loops are useful for displaying lists of products, processing user records, calculating totals, validating collections of data, generating reports, and performing repetitive operations.

Kotlin provides several looping techniques, including for, while, and do-while loops. It also supports loop-control statements such as break and continue, along with higher-order collection functions such as forEach, map, and filter.

Example

fun main() {
    for (number in 1..5) {
        println("Number: $number")
    }
}

Output:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

The loop executes five times and prints each number from 1 to 5.

2. Learning Objectives

After completing this topic, learners should be able to:

  • Understand the purpose and importance of loops in Kotlin.
  • Implement for, while, and do-while loops.
  • Use ranges and progression operators for iteration.
  • Iterate through arrays, lists, sets, and maps.
  • Use break and continue to control loop execution.
  • Understand nested loops and their applications.
  • Apply collection functions for processing data.
  • Avoid infinite loops and common iteration errors.
  • Implement loops in practical Android development scenarios.

3. Understanding the for Loop

The for loop is used to iterate through a range, array, collection, or another supported sequence of values. Kotlin's for loop is particularly useful when the elements to process are already available.

3.1 Basic for Loop

fun main() {
    for (i in 1..5) {
        println(i)
    }
}

The expression 1..5 creates a range that includes both 1 and 5. The loop processes every value in that range.

3.2 Iterating Through a List

fun main() {
    val fruits = listOf("Apple", "Banana", "Mango")

    for (fruit in fruits) {
        println(fruit)
    }
}

The loop retrieves each fruit from the list and prints it. This technique is useful when processing lists of names, products, categories, or messages in an Android application.

3.3 Iterating Through an Array

fun main() {
    val marks = arrayOf(85, 90, 78, 92)

    for (mark in marks) {
        println("Mark: $mark")
    }
}

Each element is assigned to the loop variable mark during an iteration.

3.4 Iterating with Index Values

Sometimes, a program needs both the position and the value of an element. Kotlin provides withIndex() for this purpose.

fun main() {
    val students = listOf("Aarav", "Priya", "Rohan")

    for ((index, student) in students.withIndex()) {
        println("${index + 1}. $student")
    }
}

Output:

1. Aarav
2. Priya
3. Rohan

This technique is useful for numbered lists, menus, rankings, and displaying items with their positions.

4. Working with Ranges and Progressions

Kotlin provides range and progression operators that control which values a loop processes.

4.1 The Range Operator (..)

The .. operator creates an inclusive range, meaning that both the starting and ending values are included.

for (number in 1..5) {
    println(number)
}

This loop prints numbers from 1 through 5.

4.2 The until Operator

The until operator creates a range that excludes the upper limit.

for (number in 1 until 5) {
    println(number)
}

The output contains 1, 2, 3, and 4. The value 5 is excluded.

4.3 The downTo Operator

The downTo operator iterates in descending order.

for (number in 5 downTo 1) {
    println(number)
}

This is useful for countdowns, reverse sequences, and descending numerical calculations.

4.4 The step Operator

The step operator specifies the interval between successive values in a progression.

for (number in 0..10 step 2) {
    println(number)
}

Output: 0, 2, 4, 6, 8, 10.

4.5 Combining Range Operators

fun main() {
    println("Ascending:")
    for (i in 1..5 step 2) {
        println(i)
    }

    println("Descending:")
    for (i in 10 downTo 2 step 2) {
        println(i)
    }
}

Combining these operators provides control over the starting point, ending point, direction, and interval of iteration.

5. Understanding the while Loop

A while loop repeatedly executes a block of code as long as its condition remains true. The condition is evaluated before the loop body executes.

5.1 Basic while Loop

fun main() {
    var count = 1

    while (count <= 5) {
        println(count)
        count++
    }
}

The loop starts with count = 1. After every iteration, the value increases by one. When the value becomes 6, the condition is false and the loop stops.

5.2 Using while for User Input Processing

A while loop can process values while a particular condition is satisfied. The following example simulates processing a limited number of pending tasks.

fun main() {
    var pendingTasks = 3

    while (pendingTasks > 0) {
        println("Processing task $pendingTasks")
        pendingTasks--
    }

    println("All tasks processed")
}

This example demonstrates how a changing condition controls the number of iterations.

5.3 When to Use while

  • When the number of iterations is not known in advance.
  • When repetition depends on a changing condition.
  • When waiting for a program state to change within a controlled algorithm.
  • When processing data until a termination condition is reached.

In Android applications, avoid using blocking loops on the main UI thread to wait for network responses or user actions. Use coroutines, callbacks, or other asynchronous techniques instead.

6. Understanding the do-while Loop

A do-while loop executes the loop body first and checks the condition afterward. Consequently, its body always runs at least once.

6.1 Basic Example

fun main() {
    var number = 1

    do {
        println(number)
        number++
    } while (number <= 5)
}

The loop prints numbers from 1 to 5. The condition is evaluated after each execution of the body.

6.2 Difference Between while and do-while

Feature while do-while
Condition check Before the body After the body
Minimum executions Zero One
Best suited for Repetition only while a condition is true Operations that must run at least once
Syntax while (condition) { ... } do { ... } while (condition)

6.3 Example with a False Initial Condition

fun main() {
    var number = 10

    while (number < 5) {
        println("while executed")
    }

    do {
        println("do-while executed")
    } while (number < 5)
}

The while body does not execute because its initial condition is false. The do-while body executes once before its condition is checked.

7. Loop Control Statements

Loop-control statements change the normal flow of iteration. Kotlin supports break to terminate a loop and continue to skip the remaining statements in the current iteration.

7.1 The break Statement

The break statement immediately terminates the nearest enclosing loop.

fun main() {
    for (number in 1..10) {
        if (number == 6) {
            break
        }

        println(number)
    }
}

Output: 1, 2, 3, 4, 5.

When the loop reaches 6, it stops without printing that value.

7.2 The continue Statement

The continue statement skips the remaining statements in the current iteration and proceeds to the next iteration.

fun main() {
    for (number in 1..5) {
        if (number == 3) {
            continue
        }

        println(number)
    }
}

Output: 1, 2, 4, 5.

The value 3 is skipped, but the loop continues processing the remaining numbers.

7.3 Using break in a Search Operation

fun main() {
    val numbers = listOf(10, 20, 30, 40, 50)

    for (number in numbers) {
        if (number == 30) {
            println("Value found")
            break
        }
    }
}

Once the target value is found, the loop stops searching. This can avoid unnecessary work in simple sequential searches.

7.4 Labeled break and continue

Kotlin supports labels for controlling nested loops. A labeled break exits the specified enclosing loop, while a labeled continue proceeds to the next iteration of the specified loop.

fun main() {
    outer@ for (i in 1..3) {
        for (j in 1..3) {
            if (i == 2 && j == 2) {
                break@outer
            }

            println("i=$i, j=$j")
        }
    }
}

The labeled break exits the outer loop when both conditions are met. Use labels sparingly because deeply nested control flow can make code harder to understand.

8. Nested Loops

A nested loop is a loop placed inside another loop. For every iteration of the outer loop, the inner loop can execute its own sequence of iterations.

8.1 Basic Nested Loop

fun main() {
    for (i in 1..3) {
        for (j in 1..2) {
            println("Outer: $i, Inner: $j")
        }
    }
}

The outer loop runs three times. The inner loop runs twice for each outer iteration, producing six combinations.

8.2 Printing a Pattern

fun main() {
    for (row in 1..5) {
        for (column in 1..row) {
            print("* ")
        }
        println()
    }
}

Output:

*
* *
* * *
* * * *
* * * * *

This example demonstrates nested iteration and can be used to practice loops, patterns, and output formatting.

8.3 Multiplication Table

fun main() {
    for (number in 1..5) {
        for (multiplier in 1..10) {
            println("$number x $multiplier = ${number * multiplier}")
        }
    }
}

Nested loops are useful for tabular calculations, matrix processing, grid-based algorithms, and generating combinations. However, their execution time can increase rapidly when both loops process large datasets.

9. Iterating Through Collections

Kotlin collections provide convenient ways to store and process groups of values. Iteration techniques can be applied to lists, sets, maps, and arrays.

9.1 Iterating Through a List

fun main() {
    val products = listOf("Laptop", "Phone", "Tablet")

    for (product in products) {
        println(product)
    }
}

9.2 Iterating Through a Set

fun main() {
    val categories = setOf("Electronics", "Books", "Clothing")

    for (category in categories) {
        println(category)
    }
}

A set stores unique values. Do not rely on a particular iteration order unless the selected collection type explicitly guarantees it.

9.3 Iterating Through a Map

fun main() {
    val user = mapOf(
        "name" to "Riya",
        "city" to "Mumbai",
        "role" to "Developer"
    )

    for ((key, value) in user) {
        println("$key: $value")
    }
}

Map destructuring allows the loop to access both the key and the value of each entry.

9.4 Iterating Through an Array with Indices

fun main() {
    val scores = arrayOf(80, 90, 75, 95)

    for (index in scores.indices) {
        println("Index $index: ${scores[index]}")
    }
}

The indices property provides the valid index range of the array. This helps avoid manually calculating the final index.

10. Collection Iteration Functions

In addition to traditional loops, Kotlin offers collection functions that make many data-processing operations concise and expressive.

10.1 The forEach Function

The forEach function executes an action for every element in a collection.

fun main() {
    val names = listOf("Amit", "Neha", "Karan")

    names.forEach { name ->
        println(name)
    }
}

This is useful when the same action must be applied to every element. For complex control flow, a traditional loop may be easier to read.

10.2 The map Function

The map function transforms each element into a new value and returns a list of the transformed results.

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5)
    val squares = numbers.map { number ->
        number * number
    }

    println(squares)
}

Output: [1, 4, 9, 16, 25].

10.3 The filter Function

The filter function creates a collection containing only the elements that satisfy a condition.

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6)

    val evenNumbers = numbers.filter { number ->
        number % 2 == 0
    }

    println(evenNumbers)
}

Output: [2, 4, 6].

10.4 The reduce Function

The reduce function combines collection elements into a single result. It requires a non-empty collection because the first element becomes the initial accumulator.

fun main() {
    val numbers = listOf(10, 20, 30, 40)

    val total = numbers.reduce { sum, number ->
        sum + number
    }

    println(total)
}

Output: 100. When a collection might be empty, consider fold() with an initial value or another suitable approach.

10.5 Choosing Between Loops and Collection Functions

Technique Purpose Example
for General iteration with clear control flow Processing every product
forEach Applying an action to each element Printing each name
map Transforming every element Converting prices to formatted values
filter Selecting matching elements Finding products in stock
reduce Combining elements into one result Calculating a total

11. Implementing Loops in Android Applications

Loops are commonly used in Android applications to prepare data, calculate values, and process collections before displaying results in the user interface.

11.1 Displaying a List of Products

fun main() {
    val products = listOf(
        "Laptop",
        "Smartphone",
        "Headphones",
        "Smartwatch"
    )

    for (product in products) {
        println("Product: $product")
    }
}

This demonstrates processing a product collection. In a real Android application, a RecyclerView or Jetpack Compose's LazyColumn is generally more suitable for displaying long or scrollable lists than manually creating every view in a loop.

11.2 Calculating a Shopping Cart Total

fun main() {
    val prices = listOf(500.0, 1200.0, 750.0)
    var total = 0.0

    for (price in prices) {
        total += price
    }

    println("Total: $total")
}

The loop adds each price to the running total. For real financial applications, consider using integer minor units or BigDecimal to avoid floating-point precision issues.

11.3 Filtering Active Users

data class User(
    val name: String,
    val isActive: Boolean
)

fun main() {
    val users = listOf(
        User("Aarav", true),
        User("Priya", false),
        User("Rohan", true)
    )

    for (user in users) {
        if (user.isActive) {
            println(user.name)
        }
    }
}

This example checks each user and prints the names of active users. The same selection can be expressed with users.filter { it.isActive } when a filtered collection is needed.

11.4 Processing Data in Jetpack Compose

Jetpack Compose provides collection-aware UI components. A LazyColumn is useful for displaying a scrollable list of items without creating every item at once.

import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable

@Composable
fun ProductList() {
    val products = listOf(
        "Laptop",
        "Smartphone",
        "Headphones"
    )

    LazyColumn {
        items(products) { product ->
            Text(text = product)
        }
    }
}

This example assumes that the project has Jetpack Compose and the required dependencies configured. The items() function manages list-item composition, making it preferable to manually creating a large number of UI elements in a regular loop.

11.5 Avoiding Blocking Loops on the Main Thread

Android's main thread handles user interaction and UI updates. A long-running or infinite loop on this thread can make an application unresponsive.

For tasks involving network requests, delays, or background calculations, use appropriate asynchronous techniques such as Kotlin coroutines, dispatchers, and lifecycle-aware scopes. A loop itself does not make an operation asynchronous.

12. Infinite Loops and Common Errors

An infinite loop occurs when its termination condition never becomes false or when the loop has no reachable exit. Such loops can consume CPU resources and, in Android applications, may cause the interface to freeze.

12.1 Missing Counter Update

Incorrect example:

var count = 1

// Incorrect: count never changes.
// while (count <= 5) {
//     println(count)
// }

The condition remains true because count is never updated.

Correct example:

var count = 1

while (count <= 5) {
    println(count)
    count++
}

12.2 Incorrect Boundary Conditions

for (number in 1 until 5) {
    println(number)
}

This loop intentionally excludes 5. If the requirement is to include 5, use 1..5.

12.3 Modifying a Collection During Iteration

Changing a mutable collection while iterating over it with an iterator or a collection loop can lead to unexpected behavior or a ConcurrentModificationException, depending on the collection and operation.

Safer approach when removing matching values:

fun main() {
    val numbers = mutableListOf(1, 2, 3, 4, 5)

    numbers.removeAll { number ->
        number % 2 == 0
    }

    println(numbers)
}

The output is [1, 3, 5]. The collection function expresses the removal condition without manually removing elements from inside a standard iteration loop.

12.4 Common Loop Problems

Problem Cause Solution
Infinite loop Termination condition never becomes false Check variable updates and exit conditions
Missing final value Using an exclusive range Use the correct range operator
Incorrect index Using an invalid array or list index Use indices or safe indexing
Slow execution Unnecessary nested iterations Optimize the algorithm and avoid repeated work
UI freezing Long-running loop on the main thread Use asynchronous background processing where appropriate
Unexpected collection errors Unsafe modification during iteration Use safe removal functions or a suitable iterator
Skipped processing Using continue or break incorrectly Review loop-control conditions

13. Best Practices for Implementing Loops

  • Choose the loop type that matches the problem.
  • Use a for loop when iterating through a known range or collection.
  • Use while when repetition depends on a condition checked before execution.
  • Use do-while when the body must execute at least once.
  • Make sure loop termination conditions can eventually become false.
  • Use meaningful variable names such as index, product, or student.
  • Prefer collection functions such as filter and map when they make the intended operation clearer.
  • Avoid deeply nested loops when a simpler algorithm is available.
  • Use indices or withIndex() when working with collection positions.
  • Avoid modifying collections unsafely during iteration.
  • Do not block Android's main thread with expensive or indefinite loops.
  • Test empty collections, single-element collections, and boundary values.
  • Measure performance before optimizing code unnecessarily.

14. Practical Exercises

Exercise 1: Print Numbers

Write a Kotlin program that prints numbers from 1 to 20 using a for loop.

Exercise 2: Even Numbers

Print all even numbers between 1 and 50 using a range and the step operator.

Exercise 3: Countdown Timer Logic

Use a while loop to print numbers from 10 down to 1, followed by a completion message. This exercise models countdown logic only; it does not implement a real-time Android timer.

Exercise 4: Sum of Elements

Create a list of integers and calculate the sum of its values using a for loop.

Exercise 5: Search for a Product

Create a list of product names. Search for a particular product and stop the loop when it is found using break.

Exercise 6: Skip Invalid Values

Iterate through a list of numbers and use continue to skip negative values.

Exercise 7: Multiplication Tables

Use nested loops to print multiplication tables from 1 to 10.

Exercise 8: Filter Active Users

Create a list of user records and display only the users whose active status is true.

15. Mini Project: Shopping Cart Summary

Project Objective: Develop a Kotlin program that processes shopping cart items using loops, conditions, and collection operations.

Project Requirements

  • Create a list of product names.
  • Create a corresponding list of product prices.
  • Iterate through the products and display their names and prices.
  • Calculate the total cost of all items.
  • Identify products priced above a specified threshold.
  • Display a message when the cart is empty.
  • Use clear variable names and appropriate data types.

Sample Implementation

data class Product(
    val name: String,
    val price: Double
)

fun main() {
    val cart = listOf(
        Product("Keyboard", 1200.0),
        Product("Mouse", 650.0),
        Product("Monitor", 8500.0)
    )

    if (cart.isEmpty()) {
        println("Your cart is empty")
    } else {
        var total = 0.0

        for ((index, product) in cart.withIndex()) {
            println(
                "${index + 1}. ${product.name}: ${product.price}"
            )
            total += product.price
        }

        println("Cart total: $total")

        println("Products above 1000:")

        for (product in cart) {
            if (product.price > 1000.0) {
                println(product.name)
            }
        }
    }
}

Expected Learning Outcomes

  • Apply loops to process structured data.
  • Use conditions inside loops.
  • Calculate aggregate values using iteration.
  • Access list elements and their indices.
  • Combine data classes and collections in Kotlin.

16. Interview Questions and Answers

Q1. What is a loop in Kotlin?

A loop is a control structure that repeatedly executes a block of code based on a range, collection, or condition.

Q2. What types of loops does Kotlin support?

Kotlin supports for, while, and do-while loops.

Q3. What is the difference between for and while?

A for loop commonly iterates through a range or collection, while a while loop repeats as long as its condition is true.

Q4. Why does a do-while loop execute at least once?

Because its condition is checked after the loop body executes for the first time.

Q5. What is the difference between break and continue?

break terminates the nearest enclosing loop. continue skips the remaining statements in the current iteration and moves to the next iteration.

Q6. What is a nested loop?

A nested loop is a loop inside another loop. It is commonly used for patterns, matrices, and combinations of values.

Q7. What is the difference between 1..5 and 1 until 5?

1..5 includes both endpoints, while 1 until 5 excludes the upper endpoint.

Q8. What does the step operator do?

The step operator controls the interval between successive values in a numeric progression.

Q9. How can you iterate through a list in Kotlin?

You can use a for loop, forEach, or other collection functions depending on the operation required.

Q10. What is an infinite loop?

An infinite loop is a loop that does not reach a terminating condition or exit, causing it to continue indefinitely.

Q11. How can you access both an element and its index?

Use withIndex() or iterate through the collection's indices when appropriate.

Q12. What is the purpose of the map function?

The map function transforms each element of a collection and returns a list of the transformed results.

Q13. What is the purpose of filter?

The filter function returns a collection containing elements that satisfy a specified condition.

Q14. Why should long-running loops be avoided on Android's main thread?

Long-running work on the main thread can block UI rendering and input processing, making the application unresponsive. Expensive work should be handled using appropriate asynchronous techniques.

Q15. How can you avoid errors when removing items during iteration?

Use suitable collection operations, such as removeAll with a predicate, or use a supported iterator-removal approach instead of modifying the collection unsafely during traversal.

17. Quick Revision Checklist

  • Understand the purpose of loops and iteration.
  • Practice for, while, and do-while.
  • Know the difference between inclusive and exclusive ranges.
  • Use step and downTo correctly.
  • Understand break, continue, and loop labels.
  • Practice nested loops and pattern generation.
  • Iterate through arrays, lists, sets, and maps.
  • Understand forEach, map, filter, and reduce.
  • Prevent infinite loops and invalid index access.
  • Use safe collection-modification techniques.
  • Keep long-running operations off Android's main thread.
  • Practice loop-based calculations and small Kotlin projects.

18. Conclusion

Loops and iteration techniques are essential for processing data efficiently in Kotlin. The for loop is useful for ranges and collections, while while and do-while provide condition-based repetition. Statements such as break and continue allow developers to control how loops execute.

Kotlin collection functions provide expressive alternatives for transforming, filtering, and combining data. By understanding these techniques, developers can write clearer code for Android application logic, product processing, data calculations, and list-based user interfaces.


Learn Android App Development with JustAcademy

Strengthen your Kotlin programming skills and explore practical Android application development through the JustAcademy course.

Course Details: View Android App Development Course

Register for a Demo: Register for Course Demo

JustAcademy Website: Visit JustAcademy

Previous Next
whatsapp