Groovy Switch Expressions

Groovy Switch Expressions tutorial covers pattern matching with strings, types, ranges, and more.

Groovy Switch Expressions

Groovy Switch Expressions

last modified March 20, 2025

Switch expressions in Groovy, also known as pattern matching, offer a concise way to handle multiple conditions. Unlike traditional switches, they return values, enhancing expressiveness. This tutorial explores their versatility with examples.

Simple Switch

Switch expressions use the -> syntax to return a value based on a condition, simplifying basic decision-making.

SimpleSwitch.groovy

def num = 3 def res = switch (num) { case 3 -> “three” default -> “other” } println res

switch (num) checks num (3) against cases. case 3 matches, returning “three”. The default case handles unmatched values. This compact form returns a value directly, unlike statement-based switches.

$ groovy SimpleSwitch.groovy three

Matching String Literals

Switch expressions can match string inputs, making them ideal for text-based conditions like user responses.

SwitchStrings.groovy

def res = System.console().readLine ‘Capital of Slovakia?: ' def capital = res.capitalize()

def msg = switch (capital) { case ‘Bratislava’ -> ‘correct answer’ default -> ‘wrong answer’ }

println msg

readLine gets user input, capitalized for consistency. switch (capital) checks if it’s “Bratislava”, returning “correct answer”, else “wrong answer” via default. This shows string matching with a fallback, useful for quizzes or validation.

$ groovy SwitchStrings.groovy Capital of Slovakia?: bratislava correct answer

Matching Integers

Integer matching allows switch expressions to handle numeric options, common in menu-driven programs.

SwitchIntegers.groovy

def menu = ’’’ Select option 1 - start 2 - slow down 3 - accelerate 4 - pause 5 - terminate ’’'

println menu

def opt = System.console().readLine ‘: '

def res = switch (opt as Integer) { case 1 -> ‘start’ case 2 -> ‘slow down’ case 3 -> ‘accelerate’ case 4 -> ‘pause’ case 5 -> ’terminate’ default -> ‘unknown’ }

println “your option: $res”

A menu is displayed, and opt as Integer converts input to a number. switch maps 1-5 to actions, with default for invalid inputs. This returns a string like “your option: accelerate”, demonstrating numeric pattern matching.

$ groovy SwitchIntegers.groovy
Select option
1 - start
2 - slow down
3 - accelerate
4 - pause
5 - terminate
3 your option: accelerate

Matching Types

Switch expressions can match object types, identifying the class of a value in a mixed collection.

SwitchTypes.groovy

def data = [1, 2.2, ‘falcon’, true, [1, 2, 3], 2g]

for (e in data) { def res = switch (e) { case Integer -> ‘integer’ case String -> ‘string’ case Boolean -> ‘boolean’ case List -> ’list’ default -> ‘other’ } println res }

data contains varied types. switch (e) checks each element’s type, returning a label (e.g., “integer” for 1, “list” for [1, 2, 3]). default catches BigDecimal (2g). This highlights type-based pattern matching for dynamic data.

$ groovy SwitchTypes.groovy integer other string boolean list other

Multiple Options

Comma-separated cases group multiple values under one outcome, streamlining conditions with shared results.

SwitchMultiple.groovy

def grades = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘FX’]

for (grade in grades) { switch (grade) { case ‘A’ , ‘B’ , ‘C’ , ‘D’ , ‘E’ , ‘F’ -> println(‘passed’) case ‘FX’ -> println(‘failed’) } }

grades lists academic marks. case ‘A’ , ‘B’ , … groups passing grades (A-F), printing “passed”, while ‘FX’ prints “failed”. This comma syntax consolidates multiple matches into a single action, enhancing readability.

$ groovy SwitchMultiple.groovy passed passed passed passed passed passed failed

Default Option

The default case in recursive functions provides a catch-all, demonstrating switch expressions’ return value utility.

SwitchDefault.groovy

def factorial(n) { switch (n) { case 0, 1 -> 1 default -> n * factorial(n - 1) } }

for (i in 0g..5g) { def f = factorial(i) println("$i $f") }

factorial uses switch to compute factorials. case 0, 1 returns 1 (base cases), and default recursively multiplies. The loop prints factorials from 0 to 5 (e.g., 5 120). This shows switch as an expression in recursion.

$ groovy SwitchDefault.groovy 0 1 1 1 2 2 3 6 4 24 5 120

Guards Within Options

Guards use closures to add conditions to cases, refining matches beyond simple equality.

SwitchGuards.groovy

def rnd = new Random() def ri = rnd.nextInt(-5, 5)

def res = switch (ri) { case { ri < 0 } -> “${ri}: negative value” case { ri == 0 } -> “${ri}: zero” case { ri > 0 } -> “${ri}: positive value” }

println res

ri is a random integer (-5 to 4). switch uses guards: { ri < 0 } for negatives, { ri == 0 } for zero, and { ri > 0 } for positives. Output varies (e.g., “-3: negative value”), showing dynamic condition matching.

$ groovy SwitchGuards.groovy 2: positive value // varies per run

Matching Enumerations

Enums pair naturally with switch expressions, matching specific constants for type-safe logic.

SwitchEnums.groovy

enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }

def days = [Day.Monday, Day.Tuesday, Day.Wednesday, Day.Thursday, Day.Friday, Day.Saturday, Day.Sunday]

def res = [] def random = new Random()

(0..3).each { res << days[random.nextInt(days.size())] }

for (e in res) { switch (e) { case Day.Monday -> println(“monday”) case Day.Tuesday -> println(“tuesday”) case Day.Wednesday -> println(“wednesday”) case Day.Thursday -> println(“thursday”) case Day.Friday -> println(“friday”) case Day.Saturday -> println(“saturday”) case Day.Sunday -> println(“sunday”) } }

Day enum defines weekdays. Four random days are selected, and switch matches each, printing its name (e.g., “tuesday”). Output varies, but this shows enums as switch targets, leveraging their fixed values for clarity.

$ groovy SwitchEnums.groovy friday monday sunday thursday // varies per run

Matching Enum Ranges

Switch expressions support ranges of enums, grouping consecutive values for concise logic.

SwitchEnumRanges.groovy

enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }

def isWeekend(Day d) { switch (d) { case Day.Monday..Day.Friday -> false case Day.Saturday, Day.Sunday -> true } }

def days = [Day.Monday, Day.Tuesday, Day.Wednesday, Day.Thursday, Day.Friday, Day.Saturday, Day.Sunday]

for (e in days) { if (isWeekend(e)) { println(‘weekend’) } else { println(‘weekday’) } }

isWeekend uses Monday..Friday for weekdays (false) and Saturday, Sunday for weekends (true). The loop tests all days, printing “weekday” five times, then “weekend” twice. This combines ranges and multiple matches effectively.

$ groovy SwitchEnumRanges.groovy weekday weekday weekday weekday weekday weekend weekend

Matching Objects

Switch expressions can match object types, grouping related classes for shared handling.

SwitchObjects.groovy

record Cat(String name) {} record Dog(String name) {} record Person(String name) {}

def data = [new Cat(‘Missy’), new Dog(‘Jasper’), new Dog(‘Ace’), new Person(‘Peter’), ‘Jupiter’]

for (e in data) { switch (e) { case Cat, Dog -> println("${e} is a pet") case Person -> println("${e} is a human") default -> println(‘unknown’) } }

Cat, Dog, and Person are records. case Cat, Dog groups pets, case Person matches humans, and default catches others (e.g., “Jupiter”). This prints type-based messages, showing object pattern matching.

$ groovy SwitchObjects.groovy Cat[name=Missy] is a pet Dog[name=Jasper] is a pet Dog[name=Ace] is a pet Person[name=Peter] is a human unknown

Matching Ranges

Numeric ranges in switch expressions check if a value falls within bounds, useful for categorizing numbers.

SwitchRanges.groovy

def rnd = new Random() def ri = rnd.nextInt(0, 120)

switch (ri) { case 1..30 -> println(‘value is in 1 to 30’) case 31..60 -> println(‘value is in 31 to 60’) case 61..90 -> println(‘value is in 61 to 90’) case 91..120 -> println(‘value is in 91 to 120’) }

ri is random (0-119). switch checks ranges (e.g., 1..30), printing the matching range’s message. Output varies (e.g., “value is in 61 to 90”), showing how ranges partition numeric values efficiently.

$ groovy SwitchRanges.groovy value is in 61 to 90 // varies per run

Matching Regular Expressions

Switch expressions can match strings against regex patterns, filtering based on complex criteria.

SwitchRegex.groovy

def words = [‘week’, ‘bitcoin’, ‘cloud’, ‘copper’, ‘raw’, ‘war’, ‘cup’, ‘water’]

def selected = []

for (word in words) { def res = switch (word) { case ~/^w./ -> word case ~/^c./ -> word default -> ‘skip’ } if (res != ‘skip’) { selected.add(res) } }

println selected

~/^w./ matches words starting with “w”, ~/^c./ with “c”. Matching words are returned, others get “skip”. selected collects matches (e.g., “week”, “cloud”), showing regex pattern matching in action.

$ groovy SwitchRegex.groovy [week, cloud, copper, war, cup, water]

Matching Lists (Contains)

Switch expressions can check if a value is in a list, useful for membership tests within data structures.

SwitchListContains.groovy

def users = [ [‘John’, ‘Doe’, ‘gardener’], [‘Jane’, ‘Doe’, ’teacher’], [‘Roger’, ‘Roe’, ‘driver’], [‘Martin’, ‘Molnar’, ‘programmer’], [‘Robert’, ‘Kovac’, ‘shopkeeper’], [‘Tomas’, ‘Novy’, ‘programmer’] ]

def occupation = ‘programmer’

for (user in users) { switch (occupation) { case user -> println("${user[0]} ${user[1]} is a programmer") default -> println("${user[0]} ${user[1]} is not a programmer") } }

users lists name-occupation pairs. case user checks if “programmer” is in user (the list), printing appropriately. This identifies programmers (Martin, Tomas), using list containment as a pattern.

$ groovy SwitchListContains.groovy John Doe is not a programmer Jane Doe is not a programmer Roger Roe is not a programmer Martin Molnar is a programmer Robert Kovac is not a programmer Tomas Novy is a programmer

Matching Lists (Property Check)

Switch expressions can test list properties, like checking for a value in a sublist, enhancing data queries.

SwitchListProperty.groovy

def users = [ [’name’: ‘Paul’, ‘grades’: [‘D’, ‘A’, ‘B’, ‘A’]], [’name’: ‘Martin’, ‘grades’: [‘F’, ‘B’, ‘E’, ‘FX’]], [’name’: ‘Lucia’, ‘grades’: [‘A’, ‘A’, ‘B’, ‘FX’]], [’name’: ‘Jan’, ‘grades’: [‘A’, ‘B’, ‘B’, ‘B’]] ]

for (user in users) { switch (‘FX’) { case user.grades -> println("${user.name} did not pass") } }

users maps names to grades. case user.grades checks if ‘FX’ is in the grades list, printing for failures (Martin, Lucia). This uses switch to query sublist contents, skipping non-matches implicitly.

$ groovy SwitchListProperty.groovy Martin did not pass Lucia did not pass

Source

Groovy Documentation

This tutorial explored Groovy switch expressions with examples.

Author

I’m Jan Bodnar, a passionate programmer with years of experience. Since 2007, I’ve written over 1,400 articles and 8 e-books, teaching coding for over a decade.

List all Groovy tutorials.

ad ad