Groovy Closures: Syntax, Parameters, and Collection Patterns

Definition and Invocation

A closure in Groovy is an anonymous code block enclosed in curly braces. It can be assigned to variables, passed as arguments, and invoked on demand.

def greet = { println 'Hello from Groovy' }

Invoke a closure using the call method or through direct parentheses syntax:

greet.call()
greet()

Parameter Handling

When a closure accepts no arguments, define an explicit empty parameter list with an arrow:

def noArgs = { -> println 'Running without parameters' }
noArgs()

For a single typed parameter, declare it before the arrow:

def welcome = { String user -> println "Welcome, ${user}" }
welcome('Developer')

Multiple parameters are separated by commas:

def configure = { String env, int port ->
    println "Environment: ${env}, Port: ${port}"
}
def serverPort = 8080
configure('production', serverPort)

If parameters are omitted, Groovy provides an implicit argument named it:

def echo = { println "Received: ${it}" }
echo('message')

Declaring any parameter explicitly removes the implicit it. The closure body then relies solely on the named arguments.

Return Values

Every closure evaluates to the value of its last expression. When the final statement is a method call that yields nothing, or when the block is empty, the result is null:

def printer = { println "Value: ${it}" }
def outcome = printer('sample')
println outcome  // null

Use an explicit return or simply let the final expression stand as the result:

def formatter = { return "Formatted: ${it}" }
def result = formatter('data')
println result

Iterating with Numeric Ranges

Closures integrate tightly with numeric types to provide concise iteration.

The upto method counts upward through a range, inclusive of both endpoints:

3.upto(8) { println it }

This pattern simplifies accumulation tasks:

def sum = 0
1.upto(100) { sum += it }
println sum

For downward iteration, use downto:

10.downto(4) { println it }

The times method repeats from zero up to, but not including, the given number:

5.times { println it }

It can also drive aggregate calculations:

def total = 0
11.times { total += it }
println total

When a closure is the final argument to a method, Groovy allows it to appear outside the parentheses:

// idiomatic
3.upto(7) { println it }

// valid but less common
3.upto(7, { println it })

Processing Strings and Collections

Closures serve as the primary mechanism for traversing and transforming strings.

def phrase = "Groovy 4.0 Release"

// Iterate over each character
phrase.each { println it }

// Locate the first digit
println phrase.find { it.isNumber() }

// Gather all digits
def numbers = phrase.findAll { it.isNumber() }
println numbers

// Check if any character satisfies a condition
println phrase.any { it.isNumber() }

// Verify that all characters satisfy a condition
println phrase.every { it.isNumber() }

// Transform each element and collect results
def transformed = phrase.collect { it.toUpperCase() }
println transformed

Note that find expects the closure to evaluate to a boolean for matching, while each returns the original collection (or string) after completion.

Tags: Groovy closures JVM programming

Posted on Tue, 15 Sep 2026 16:33:38 +0000 by tdors