1. Introduction

Loops are one of the basic constructs of any programming language. They allow for repeated execution of one or more statements until a condition is met.

In this tutorial, we’re going to look at the different types of loops supported by Kotlin:

  • repeat
  • for loop
  • while loop
  • do..while loop

Let’s start by looking at the repeat statement.

2. Repeat

The repeat statement is the most basic of all the Kotlin loops. If we wish to simply repeat an operation n times, we can use repeat.

For example, let’s print Hello World two times:

repeat(2) {
    println("Hello World")
}

Additionally, we can also access the zero-based index of the current iteration:

repeat(2) { index ->
    println("Iteration ${index + 1}: Hello World")
}

3. For Loop

A for loop is used for iterating over a sequence of values. It executes a block of statements for each value in the sequence.

Let’s start by looking at the syntax of the for loop:

for (variableDeclaration 'in' expression) {
    // block of statements
}

Using Kotlin’s for loop, we can iterate over any Iterable such as a range, an array, or a collection.

3.1. Iterating Over a Range of Values

A range is a sequence of values comprising of a start, an end, and a step. In Kotlin, we can iterate over a range using a combination of the for loop and range expressions.

3.2. Iterating Over an Array

To begin with, let’s declare an array of vowels:

val vowels = arrayOf('a', 'e', 'i', 'o', 'u')

We can now iterate over the elements of this array using the for loop:

for (vowel in vowels) {
    println(vowel)
}

Next, let’s iterate over the array indices. We can do this by looping over the indices property:

for (index in vowels.indices) {
    println(vowels[index])
}

The indices property returns only the array indices as an IntRange that we can iterate over. We have to fetch the array elements separately using the returned indices.

Let’s look at an alternate way that gives us both the indices and elements at the same time:

for ((index, vowel) in vowels.withIndex()) {
    println("The vowel at index $index is: $vowel")
}

Let’s understand the interesting syntax of this for a loop a bit more:

for ((index, vowel) in vowels.withIndex()) { ... }

The withIndex() method returns an IndexedValue instance. We use the destructuring declarations and capture the (index, value) properties returned by the component1() and component2() methods of the IndexedValue into the index and vowel variables respectively.

3.3. Iterating Over a List

A list is a generic ordered collection of elements that can contain duplicate values. We can use the for loop to iterate over the elements of a list. We can also iterate over a list by the indices of its elements.

3.4. Iterating Over a Map

Let’s start by declaring a Map of capital city names keyed by country names:

val capitalCityByCountry = mapOf("Netherlands" to "Amsterdam",
  "Germany" to "Berlin", "USA" to "Washington, D.C.")

We can now iterate over the map entries and access both the key and the value of each entry:

for (entry in capitalCityByCountry) {
    println("The capital city of ${entry.key} is ${entry.value}")
}

We can iterate over the map’s keys using the keys property:

for (country in capitalCityByCountry.keys) {
    println(country)
}

Here, we iterate over the keys property that returns a read-only Set of the map’s keys.

Similarly, we can iterate over the map’s values using the values property:

for (capitalCity in capitalCityByCountry.values) {
    println(capitalCity)
}

Finally, as in the case of arrays and lists, we can use the destructuring declarations when iterating over a map as well:

for ((country, capitalCity) in capitalCityByCountry) {
    println("The capital city of $country is $capitalCity")
}

The destructuring declaration gives us access to the key and value of each entry as we iterate over the map.

3.5. Functional Style Iteration Using forEach

So far, we looked at the traditional style of iterating over arrays, collections, and ranges using the for loop.

To code in a functional style, we can use forEach instead.

4. While Loop

The while loop repeats a block of statements while its controlling Boolean-expression is true.

Let’s look at the syntax first:

while (boolean-expression) {
    // statements here
}

Next, let’s look at an example:

var counter = 0
while (counter < 5) {
    println("while loop counter: " + counter++)
}

This prints the counter values from 0 to 4.

In a while loop, the boolean-expression is evaluated first. This means that if the boolean-expression evaluates to false for the very first iteration, the block of statements will never be executed.

Here is a while loop whose block of statements will never be executed:

while (false) {
    println("This will never be printed")
}

Here is an infinite while loop:

while (true) {
    println("I am in an infinite loop")
}

5. Do..While Loop

The do..while loop is a variant of the while loop in that the boolean-expression is evaluated after each iteration:

do {
    // statements here
} while (boolean-expression)

Let’s look at a simple example:

var counter = 0
do {
    println("do..while counter: " + counter++)
} while (counter < 5)

This prints the counter values from 0 to 4.

Because the boolean-expression is evaluated at the end of each loop, the do..while loop is executed at least once.

Here is a do..while loop whose block of statements will be executed exactly once:

do {
    println("This will be printed exactly once")
} while (false)

6. The return, break, and continue Keywords

Sometimes, we might wish to terminate a loop or skip the next iteration of a loop. We can use the structural jump expressions in such cases.

Kotlin has three structural jump expressions: return, break, and continue

However, when a loop contains more than one break or continue statements, it is considered a code-smell and must be avoided.

7. Conclusion

In this tutorial, we looked at various loops supported by Kotlin. To begin with, we looked at repeat, which is the simplest of the loop statements. Then, we looked at the for loop and how it can be used to iterate over ranges, arrays, and collections. Next, we looked at the while and do..while loops and the subtle differences between them. Finally, we looked at Kotlin’s structural jump expressions: return, break and continue.

As always, the source code is available over on GitHub.

guest
0 Comments
Inline Feedbacks
View all comments