Decisions
Choosing a branch with if and switch, the two shorthands worth knowing — the ternary and the Elvis operator — and the values Groovy treats as false.
if, else if, else
An if takes a condition in parentheses and runs the block after it when the condition is true. else if asks another question when the first one failed, and a final else catches everything left over. The order is the logic: the first true branch wins, so the most specific question goes first. Put a broad test above a narrow one and the narrow branch becomes unreachable: a score >= 60 case placed before score >= 90 means the top grade can never be printed.
Groovy reads a block without braces when there is a single statement, but braces stay better advice: they keep the shape of the branches visible and they stop the next line you add from landing outside the condition.
switch, which knows about ranges
switch compares one value against a series of cases and runs the first that matches. Unlike C or Java, Groovy's cases can be ranges (case 70..89), lists, classes or regular expressions, so a score can be banded without writing four comparisons. A range case is tested with contains, so the range is an ordinary value rather than special syntax, and the half-open form case 70..<90 works in exactly the same place.
Each case needs a break unless you mean to fall through, and a default handles everything unmatched. Falling through on purpose is legal and occasionally tidy; forgetting the break by accident is one of the oldest bugs in the language, so the default is to write it.
Two shorthands, and what is false
The ternary operator chooses between two values: score >= 60 ? 'pass' : 'fail'. The Elvis operator ?: is the ternary with the test repeated on the left: nickname ?: 'anonymous' answers the nickname if it is truthy and the fallback if it is not. It is the usual way to fill in a default that arrived empty. The symptom of a truthiness mistake is a branch that runs when you expected it to stop: an empty list is false, but a list holding a single zero is true, because it is not empty.
Truthiness in Groovy is broader than in Java: null, false, the number zero, an empty string, an empty list and an empty map are all false; everything else is true. That is what lets if (list) mean "if there is anything in it" — useful, and worth reading twice in someone else's code.
Branches, bands and defaults
def temperature = 31
if (temperature > 30) {
println 'hot'
} else if (temperature > 18) {
println 'warm'
} else {
println 'cold'
}
def coat = temperature < 15 ? 'take a coat' : 'no coat'
println coat
def name = null
println(name ?: 'guest')
switch (temperature) {
case 0..15:
println 'cold snap'
break
case 16..30:
println 'mild'
break
default:
println 'hot spell'
}Comparisons produce values
A condition is just an expression that answers true or false, which is why it can be stored: def adult = age >= 18. == in Groovy means equal by content, not the same object — two separate strings with the same letters are ==. Use is() when you truly mean the same object, which is rare.
&& and || short-circuit. In ready && check(), check() is not called when ready is false; in cached || load(), load() is not called when cached is true. That is not an optimisation detail: it is how a guard such as name != null && name.size() > 3 avoids calling a method on null.
switch tests cases in order
Groovy's switch is more general than Java's. A case 70..89 asks whether the value is in the range; a case String asks whether it is an instance of that class; a case with a pattern asks whether a string matches it. Every case is tested from top to bottom, and the first match wins.
Falling through happens when a case has no break: execution continues into the next case's body. That is occasionally useful for grouping labels, and usually a missing line. default is not required, but a switch without one silently does nothing for an unmatched value.
Three decision mistakes: = assigns where == compares, and Groovy will often let the assignment's value stand in as a condition; & and | evaluate both sides and work bit by bit, so use && and || for logic; and the string 'false' is true, because it is a non-empty string. Truthiness is about emptiness and zero, not about the word.
Try these next
- Store the result of a comparison in a variable and print its type.
- Rewrite an if/else chain as a switch over ranges.
- Make a condition that uses
&&to guard a null check, then remove the guard and see the failure.
Grade a score, three ways
Run it and read the four kinds of decision. Then change `score` to 95 and to 40 and predict the output before you run it. Finally, make the Elvis fallback use an empty string instead of a missing one.
A shipping quote
Run it and trace the total. Then change the zone to `US` and the coupon to `SAVE`, and predict the new total before you run it.
An Elvis expression is not a test for "was it set". An empty string is false, so name ?: 'guest' replaces an empty name as well as a missing one — usually what you want, occasionally not.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
In an if / else if / else chain, which branch runs?
