What break does
A for loop normally visits every element. The break statement ends the loop early: as soon as Kotlin reaches it, the loop stops, no condition is checked again, and the program continues with the first statement after the loop.
Here, the loop stops when it finds a banana:
val fruits = arrayOf("kivi", "orange", "banana", "apple", "pear")
for (fruit in fruits) {
println(fruit)
if (fruit == "banana") {
break
}
}
kivi
orange
banana
"apple" and "pear" are never visited. Each iteration does the same three things: assign the next element to fruit, print it, and test it. The first two iterations find that the test is false and carry on. In the third, the test is true, so break runs and the loop is over.
The same loop with indices
Break works the same way when the loop runs over indices. Using fruits.indices gives the position as well as the element:
for (i in fruits.indices) {
println("Index $i: ${fruits[i]}")
if (fruits[i] == "banana") {
break
}
}
Index 0: kivi
Index 1: orange
Index 2: banana
This is the form to use when you need the position of the match, for example to report where the banana was. The string template "Index $i: ${fruits[i]}" inserts values into the text; $i works for a simple name, and braces are needed for an expression like fruits[i].
Where the break goes matters
The lesson's loop prints first and checks second, so the matching element is included in the output. Swapping the two statements changes the result:
for (fruit in fruits) {
if (fruit == "banana") {
break
}
println(fruit)
}
kivi
orange
Now the check happens before the print, so the banana is not printed. Decide whether the element that triggers the stop should be processed, and put break after or before that processing to match.
Break and nested loops
A plain break leaves only the innermost loop it is written in. With a loop inside a loop, the outer loop carries on:
val grid = arrayOf(intArrayOf(1, 2), intArrayOf(3, 4))
for (row in grid) {
for (v in row) {
if (v == 2) break
println(v)
}
}
1
3
4
When the inner loop reaches 2 it stops, but the outer loop moves on to the next row. To leave both loops, Kotlin lets you name the outer loop with a label and break to it:
outer@ for (row in grid) {
for (v in row) {
if (v == 2) break@outer
println(v)
}
}
This prints only 1. Labels are rarely needed; reach for one only when a nested loop must stop completely.
The exercise
The starting code has an array of lessons and the last one the student finished:
val lessons = arrayOf("variables", "conditionals", "arrays", "functions", "loops")
val lastFinishedLesson = "functions"
The task is to print every lesson up to and including the last finished one, and nothing after it. The steps:
- Loop over the array.
for (lesson in lessons)hands out each lesson in order. No index is needed, because only the values matter. - Print the lesson. Print
"Finished "joined withlessonusing+. - Stop after the last finished one. Compare
lessonwithlastFinishedLesson, and when they are equal,break. Because the comparison comes after the print, the last finished lesson is printed before the loop ends.
val lessons = arrayOf("variables", "conditionals", "arrays", "functions", "loops")
val lastFinishedLesson = "functions"
for (lesson in lessons) {
println("Finished " + lesson)
if (lesson == lastFinishedLesson) {
break
}
}
The output is:
Finished variables
Finished conditionals
Finished arrays
Finished functions
"loops" is never reached. In Kotlin, == on strings compares their contents, so lesson == lastFinishedLesson is true exactly when the two texts are equal. If no lesson matched, the loop would simply run to the end and print all five.
When to use break, and common mistakes
Break fits searches: once the loop has found what it was looking for, visiting the rest of the array is wasted work. In the worst case, when nothing matches, the loop still runs to the end, so break saves time on average but doesn't change the worst case.
- Break outside a loop.
breakis only valid inside a loop. Anywhere else the compiler reports an error. - Expecting break to leave the function. It only leaves the loop. Statements after the loop still run. To end the whole function, use
return. - Printing before or after the check by accident. If the output has one line too many or too few at the end, check the order of the print and the
if. - Forgetting the braces. The
ifand itsbreakmust both sit inside the loop's braces. Abreakthat falls outside the loop body is an error.
Key takeaways
breakends the loop immediately; the code after the loop runs next.- Whether the triggering element is processed depends on whether the work comes before or after the
breakcheck. - A plain
breakaffects only the innermost loop; use a label such asbreak@outerto leave an outer one.