Groovy Loops
last modified June 26, 2026
Loops allow programs to repeat code blocks until a condition is met or a collection is exhausted. Groovy provides while, for, and for-in loops from Java, as well as its own iteration methods like each, times, upto, and step.
Basic Definition
A loop repeats a block of code a number of times or until a condition is no longer true. Groovy supports the standard Java loop constructs and adds several convenient closure-based methods on numbers and collections.
Groovy loops integrate with closures, making iteration concise. The each, times, upto, downto, and step methods are idiomatic Groovy alternatives to traditional for loops.
while Loop
The while loop repeats its body as long as the condition evaluates to true.
def i = 0
while (i < 5) {
println i
i++
}
The variable i starts at 0 and the loop body runs while i is less than 5. The increment i++ advances the counter on each iteration.
The condition is checked before each iteration. If it is false from the start, the body never executes.
$ groovy WhileExample.groovy 0 1 2 3 4
do-while Loop
The do-while loop executes the body at least once, then checks the condition.
def n = 1
do {
println n
n *= 2
} while (n <= 16)
This prints powers of 2 starting from 1 up to 16. The body runs first and the condition is evaluated afterwards, so the loop runs at least once.
Use do-while when the body must execute at least once regardless of the initial condition value.
$ groovy DoWhileExample.groovy 1 2 4 8 16
Classic for Loop
The classic C-style for loop combines initialization, condition, and update in one statement.
for (int i = 1; i <= 5; i++) {
println "Item $i"
}
The loop initializes i to 1, runs while i is 5 or less, and increments i after each iteration. The body prints the current item number.
The three parts of the for statement are separated by semicolons. Any of them can be omitted, turning the loop into an infinite loop if the condition is left out.
$ groovy ForExample.groovy Item 1 Item 2 Item 3 Item 4 Item 5
for-in Loop
The for-in loop iterates over the elements of a collection or range.
def fruits = ["apple", "banana", "cherry", "date"]
for (fruit in fruits) {
println fruit
}
This iterates over every element in the fruits list, binding each element to the variable fruit in turn.
The for-in loop works with any Iterable, including lists, maps, ranges, strings, and arrays.
$ groovy ForInExample.groovy apple banana cherry date
Iterating over a Range
Groovy ranges can be used directly in a for-in loop.
for (i in 1..5) {
print "$i "
}
println()
for (i in 1..<5) {
print "$i "
}
println()
The .. operator creates an inclusive range. The ..< operator creates a half-open range that excludes the upper bound.
Ranges work with integers, characters, and other Comparable types. They are common in Groovy for compact loop expressions.
$ groovy ForRangeExample.groovy 1 2 3 4 5 1 2 3 4
each Method
The each method iterates over a collection and passes each element to a closure.
def colors = ["red", "green", "blue"]
colors.each { color ->
println color.toUpperCase()
}
The closure receives each element as its parameter. The arrow -> separates the parameter from the closure body.
When a closure has a single parameter, the implicit variable it can be used instead of declaring a named parameter.
$ groovy EachExample.groovy RED GREEN BLUE
eachWithIndex Method
The eachWithIndex method provides both the element and its zero-based index to the closure.
def languages = ["Groovy", "Java", "Kotlin", "Scala"]
languages.eachWithIndex { lang, idx ->
println "${idx + 1}. $lang"
}
The closure receives the element as the first argument and the index as the second. Here the index is shifted by one for a human-readable numbered list.
eachWithIndex is the idiomatic Groovy alternative to a classic for loop with a counter variable.
$ groovy EachWithIndexExample.groovy 1. Groovy 2. Java 3. Kotlin 4. Scala
times Method
The times method on integers executes a closure a fixed number of times.
5.times {
print "* "
}
println()
3.times { i ->
println "Iteration $i"
}
Without a named parameter the closure body simply runs the given number of times. With a named parameter the closure receives the current iteration index, starting at 0.
times is a concise alternative to a for loop when the exact number of repetitions is known.
$ groovy TimesExample.groovy * * * * * Iteration 0 Iteration 1 Iteration 2
upto and downto Methods
The upto and downto methods count from one integer to another, inclusive.
1.upto(5) { n ->
print "$n "
}
println()
5.downto(1) { n ->
print "$n "
}
println()
upto counts upward from the receiver to the argument. downto counts downward. Both methods include the start and end values.
These methods are readable alternatives to for loops when traversing an ascending or descending numeric sequence.
$ groovy UptoDowntoExample.groovy 1 2 3 4 5 5 4 3 2 1
step Method
The step method on ranges iterates with a custom increment.
(0..20).step(5) { n ->
print "$n "
}
println()
(10..1).step(-3) { n ->
print "$n "
}
println()
The step method accepts a positive or negative increment and passes each stepped value to the closure. A negative step iterates downward.
step is useful when elements need to be skipped at regular intervals without manually managing a counter variable.
$ groovy StepExample.groovy 0 5 10 15 20 10 7 4 1
Iterating over a Map
The each method on a map receives each key-value pair as a Map.Entry.
def capitals = [France: "Paris", Germany: "Berlin", Japan: "Tokyo"]
capitals.each { country, capital ->
println "$country -> $capital"
}
When the closure declares two parameters, Groovy destructures the entry into key and value automatically.
Map iteration order follows the insertion order of a LinkedHashMap, which is the default map type in Groovy literals.
$ groovy MapEachExample.groovy France -> Paris Germany -> Berlin Japan -> Tokyo
break Statement
The break statement exits the innermost loop immediately.
def numbers = [3, 7, 2, 9, 1, 5, 8]
for (num in numbers) {
if (num == 9) {
println "Found 9, stopping."
break
}
println num
}
When num equals 9, the break statement exits the for-in loop. Numbers after 9 in the list are never processed.
break works inside while, do-while, and for loops. It only exits the immediately enclosing loop, not outer loops.
$ groovy BreakExample.groovy 3 7 2 Found 9, stopping.
continue Statement
The continue statement skips the rest of the current iteration and moves to the next one.
for (i in 1..10) {
if (i % 2 == 0) continue
print "$i "
}
println()
Even numbers are skipped by continue. The loop continues with the next value of i, so only odd numbers are printed.
continue is available in while, do-while, and for loops. It is not directly supported inside Groovy closure-based iterators like each.
$ groovy ContinueExample.groovy 1 3 5 7 9
Nested Loops
Loops can be nested inside other loops to work with multi-dimensional data.
for (i in 1..3) {
for (j in 1..3) {
print "${i * j}\t"
}
println()
}
The outer loop iterates over rows and the inner loop over columns, producing a 3x3 multiplication table. The \t character inserts a tab for alignment.
Each iteration of the outer loop triggers a full run of the inner loop. The total number of body executions is the product of both loop counts.
$ groovy NestedLoopsExample.groovy 1 2 3 2 4 6 3 6 9
Infinite Loop
A loop without a terminating condition runs indefinitely until break or a return is encountered.
def counter = 0
while (true) {
counter++
if (counter == 5) break
}
println "Loop ended after $counter iterations"
The condition true never becomes false, so break is the only way to exit. Here the loop stops when counter reaches 5.
Infinite loops are used in event loops, servers, and retry logic. Always ensure a break condition is reachable to avoid hanging the program.
$ groovy InfiniteLoopExample.groovy Loop ended after 5 iterations
collect Method
The collect method transforms each element of a collection and returns a new list with the results.
def numbers = [1, 2, 3, 4, 5]
def squares = numbers.collect { it * it }
println squares
The closure receives each element via the implicit it variable and returns the squared value. collect gathers all returned values into a new list.
collect is the Groovy equivalent of map in functional programming. It does not modify the original collection.
$ groovy CollectExample.groovy [1, 4, 9, 16, 25]
Source
Groovy Looping Structures Documentation
This tutorial covered Groovy loop constructs including while, for, each, times, upto, downto, step, and loop control statements.
Author
List all Groovy tutorials.