Control Flow and Groovy Truth

8.1 Groovy Truth

"" (empty string/GString) Empty collection/map/array Matcher without a match Iterator/Enumeration with no elements

Object with asBoolean() returning false

if ([]) println "won't print"
if ("text" && [1] && 42) println "all truthy"
def name = ""
println name ?: "default"

8.2 if / else and the Ternary

if (x > 0) println "positive"
else if (x < 0) println "negative"
else println "zero"
def label = x > 0 ? "pos" : "non-pos"

8.3 Powerful switch

Cases use isCase(): values (equals), classes (instanceof), ranges/collections (contains), regex (match), closures (truthy result).

def describe(x) {
    switch (x) {
        case null: return "null"
        case 0: return "zero"
        case Integer: return "integer"                 // type check
        case 1..9: return "digit"                      // range
        case ['a', 'b', 'c']: return "abc"             // list membership
        case ~/\d+/: return "numeric string"           // regex
        case { it instanceof String && it.size() > 10 }: return "long string"   // closure
        default: return "other"
    }
}

8.4 Switch Expressions (Groovy 4)

def result = switch (day) {
    case 'SAT', 'SUN' -> 'weekend'
    case ~/^MON|TUE|WED|THU|FRI$/ -> 'weekday'
    default -> {
        println "unknown"
        'invalid'
    }
}

8.5 Loops

break/continue don't work inside each closures. Use for loops, find/any (which short-circuit), or return (which skips to the next element).

for (int i = 0; i < 3; i++) println i            // classic
for (i in 0..<3) println i                       // for-in over a range
for (item in ['a', 'b']) println item
for (entry in [a: 1, b: 2]) println "$entry.key=$entry.value"
for (def (i, j) = [0, 0]; i < 3; i++, j += 2) {} // multi-assignment in a for loop (Groovy 3+)
def n = 0
while (n < 5) n++
do { n-- } while (n > 0)                         // do-while (Groovy 3+)
3.times { println it }
[1, 2, 3].each { println it }
[1, 2, 3].eachWithIndex { v, i -> println "$i: $v" }
outer:
for (i in 1..3) {
    for (j in 1..3) {
        if (i * j == 4) break outer
        if (j > i) continue outer
    }
}