Grails Cookbook - A collection of tutorials and examples

Groovy Enum Examples

Enum was introduced in Java to represent a fixed set of constants. Since Groovy is a superset of Java, Enums are also supported in the Groovy programming language. Groovy also adds some enhancements to make working with Enums easier. Below are some examples on how to work with Enums in Groovy.

Groovy Declare Enum

Declaring Enum in Groovy is the same in Java. Here are some examples:
enum MyColors{
  BLUE, RED, WHITE
}
println MyColors.values()
Will output
[BLUE, RED, WHITE]
Enums can have properties
enum MyCoin{
	PENNY(1), NICKEL(5), DIME(10), QUARTER(25)
	MyCoin(int value) {
		this.centValue = value
	}
	private final int centValue
	int getCentValue() {
		centValue
	}
	public String toString() {
		return name() + " = " + centValue
	}
}
println MyCoin.values()
Will show:
[PENNY = 1, NICKEL = 5, DIME = 10, QUARTER = 25]

Groovy String to Enum

A common use case is to convert a String to an Enum. This is practically easy in Groovy. Here is a simple example:
enum MyDays{
	SUNDAY(0), MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6)
	MyDays(int value) {
		this.value = value
	}
	private final int value
	int getValue() {
		value
	}
}
String dayAsString = 'WEDNESDAY'
MyDays dayAsEnum = dayAsString as MyDays
println dayAsEnum
println dayAsEnum.value
The as operator will find an enum that matches the given String. The output will be:
WEDNESDAY
3
In fact the as operator is optional. Here is the modified example removing as:
enum MyDays{
	SUNDAY(0), MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6)
	MyDays(int value) {
		this.value = value
	}
	private final int value
	int getValue() {
		value
	}
}
String dayAsString = 'TUESDAY'
MyDays dayAsEnum = dayAsString
println dayAsEnum
println dayAsEnum.value
The output will still get it right
TUESDAY
2

Groovy Loop Through Enum Values

We can use some of Groovy way of looping through collections and apply them to Enums. Here is an example on how to loop through Enum values in Groovy:
enum MyShape{
	CIRCLE(0), TRIANGLE(3), SQUARE(4), PENTAGON(5)
	MyShape(int sides) {
		this.sides = sides
	}
	private final int sides
	int getSides() {
		sides
	}
}
for (sh in MyShape.values()) {
	println sh.name()
}
or
enum MyShape{
	CIRCLE(0), TRIANGLE(3), SQUARE(4), PENTAGON(5)
	MyShape(int sides) {
		this.sides = sides
	}
	private final int sides
	int getSides() {
		sides
	}
}
MyShape.values().each { sh ->
	println sh.name()
}
Will display the same output:
CIRCLE
TRIANGLE
SQUARE
PENTAGON

Groovy Enum Next And Previous

We can go through what is next in the sequence of enums in Groovy using the next() method inherent to the enums. For example:
enum MyFood {
	APPLE, BANANA, CARROT 
}
MyFood f = MyFood.APPLE
println "Food is ${f}"
println "Food is ${f.next()}"
As the next value is BANANA after APPLE, the output will be:
Food is APPLE
Food is BANANA
next is circular, for example:
enum MyFood {
	APPLE, BANANA, CARROT 
}
MyFood f = MyFood.APPLE
println "Food is ${f}"
println "Food is ${f.next()}"
println "Food is ${f.next().next()}"
println "Food is ${f.next().next().next()}"
println "Food is ${f.next().next().next().next()}"
Which means we can call next on any of the value as it will go to the first item if we are in the last. The sample will print:
Food is APPLE
Food is BANANA
Food is CARROT
Food is APPLE
Food is BANANA
If we want the opposite direction, we can use previous on an enum in Groovy, example:
enum MyFood {
	APPLE, BANANA, CARROT 
}
MyFood f = MyFood.CARROT
println "Food is ${f}"
println "Food is ${f.previous()}"
println "Food is ${f.previous().previous()}"
println "Food is ${f.previous().previous().previous()}"
println "Food is ${f.previous().previous().previous().previous()}"
The method previous() will get the item before the value, going backwards. Here is the expected output:
Food is CARROT
Food is BANANA
Food is APPLE
Food is CARROT
Food is BANANA
We can use the ++ operator on an Enum in Groovy to make the instance of the variable change to the next value. For example:
enum MyFood {
	APPLE, BANANA, CARROT 
}
MyFood f = MyFood.APPLE
for (i in 1..5) {
	f++
	println "Food is ${f}"
}
Note that the value of f is changed on each invocation of the operator. f++ is similar to the code f = f.next(). The code will thus render:
Food is BANANA
Food is CARROT
Food is APPLE
Food is BANANA
Food is CARROT
And we can of course call the -- operator on an Enum in Groovy , to have the variable change to the previous value.
enum MyFood {
	APPLE, BANANA, CARROT 
}
MyFood f = MyFood.CARROT
for (i in 1..5) {
	f--
	println "Food is ${f}"
}
The value of f is changed on each invocation of the operator and assigned the previous value. f-- is similar to the code f = f.previous(). The code will then render:
Food is BANANA
Food is APPLE
Food is CARROT
Food is BANANA
Food is APPLE

Groovy Enum MIN_VALUE and MAX_VALUE

We can call the MIN_VALUE of an Enum to get the first item in the possible values:

enum MyFriends {
	ANDRE, BRENT, CAROL, DIANE, EULER 
}
println "Min value is: " + MyFriends.MIN_VALUE

This will render the first item which is ANDRE:
Min value is: ANDRE
Similarly, ee can call the MAX_VALUE of an Enum to get the last item in the possible values:
enum MyFriends {
	ANDRE, BRENT, CAROL, DIANE, EULER 
}
println "Max value is: " + MyFriends.MAX_VALUE
Will render:
Max value is: EULER
Note that this is not alphabetical order, but purely on how it appears in the listing. For example:
enum MyFriends {
	XANDRE, BRENT, CAROL, DIANE, ANGELICA 
}
println "Min value is: " + MyFriends.MIN_VALUE
println "Max value is: " + MyFriends.MAX_VALUE
Will output:
Min value is: XANDRE
Max value is: ANGELICA

Groovy Enum in Range

We can use Groovy Enum to declare a Range. For example:

enum MyTools {
	DRILL, HAMMER, KNIFE, PLIERS, SCREW_DRIVER, TABLE 
}
println MyTools.KNIFE..MyTools.TABLE

Will print:
[KNIFE, PLIERS, SCREW_DRIVER, TABLE]
Like any Range or list, we can iterate through the Range declared using Enums:
enum MyTools {
	DRILL, HAMMER, KNIFE, PLIERS, SCREW_DRIVER, TABLE 
}
for (tool in MyTools.HAMMER..MyTools.SCREW_DRIVER) {
	println tool
}

Will display:

HAMMER
KNIFE
PLIERS
SCREW_DRIVER

We can declare Range using Enums in reverse order:
enum MyTools {
	DRILL, HAMMER, KNIFE, PLIERS, SCREW_DRIVER, TABLE 
}
println MyTools.SCREW_DRIVER..MyTools.DRILL
[SCREW_DRIVER, PLIERS, KNIFE, HAMMER, DRILL]

Even when we are not dealing with IntRange, we can use step to narrow down items in our range:

enum MyTools {
	DRILL, HAMMER, KNIFE, PLIERS, SCREW_DRIVER, TABLE 
}
def myRange = MyTools.DRILL..MyTools.TABLE
println myRange.step(2)
println myRange.step(3)
The code will output:
[DRILL, KNIFE, SCREW_DRIVER]
[DRILL, PLIERS]