UPDATE: This post underwent significant updates on 17 November 2016 to correct erroneous statements and examples, to fix the underlying HTML layout (not obvious to readers unless you view HTML source in a web browser), and to fix some spelling issues.
I have blogged before regarding Groovy's support for switching on String. Groovy can switch on much more than just literal String
s (and literal integral types that Java allows switching on) and I demonstrate this briefly here.
Groovy's switch
statement will use a method implemented with the name "isCase
" to determine if a particular switch
option is matched. This means that custom objects are "switchable" in Groovy. For the simple example in this blog post, I'll use the Java classes SimpleState
and State.java
.
SimpleState.java
package dustin.examples; import static java.lang.System.out; /** * Java class to be used in demonstrating the "switch on steroids" in Groovy. * The Groovy script will be able to {@code switch} on instances of this class * via the implicit invocation of {@code toString()} if the {@code case} * statements use {@code String}s as the items to match. */ public class SimpleState { private String stateName; public SimpleState(final String newStateName) { this.stateName = newStateName; } @Override public String toString() { return this.stateName; } }
The above Java class's String
representation can be switched on in a Groovy script as shown in the next code listing for switchOnSimpleState.groovy
:
switchOnSimpleState.groovy
#!/usr/bin/env groovy import dustin.examples.SimpleState SimpleState state = new SimpleState("Colorado") print "The motto for the state of ${state.stateName} is '" switch (state) { case "Alabama": print "Audemus jura nostra defendere" break case "Alaska": print "North to the future" break case "Arizona": print "Ditat Deus" break case "Arkansas": print "Regnat populus" break case "California": print "Eureka" break case "Colorado": print "Nil sine numine" break case "Connecticut": print "Qui transtulit sustinet" break default : print "<<State ${state.stateName} not found.>>" } println "'"
When the above Groovy script is run against the above simple Java class, the code prints out the correct information because Groovy implicitly invokes the toString()
method on the "state" instance of State
being switched on. Similar functionality can now be achieved in Java, but one needs to explicitly call toString()
on the object being switched on. It's also worth keeping in mind that when I wrote the original version of this post in early 2010, Java did not support switching on Strings. The output of running the above is shown in the screen snapshot below (the name of the script doesn't match above because this is an old screen snapshot from this original post before it was corrected and updated).
With Groovy and the isCase
method, I can switch on just about any data type I like. To demonstrate this, the Java class State
will be used and its code listing is shown below. It includes a isCase(State)
method that Groovy will implicitly call when instances of State
are being switched against as the case
choices. In this case, the isCase(State)
method simply calls the State.equals(Object)
method to determine if that case
is true. Although this is the typical behavior for implementations of isCase(Object)
, we could have had it determine if it was the case or not in any way we wanted.
State.java
package dustin.examples; import static java.lang.System.out; public class State { private String stateName; public State(final String newStateName) { this.stateName = newStateName; } /** * Method to be used by Groovy's switch implicitly when an instance of this * class is switched on. * * @param compareState State passed via case to me to be compared to me. */ public boolean isCase(final State compareState) { return compareState != null ? compareState.equals(this) : false; } public boolean equals(final Object other) { if (!(other instanceof State)) { return false; } final State otherState = (State) other; if (this.stateName == null ? otherState.stateName != null : !this.stateName.equals(otherState.stateName)) { return false; } return true; } @Override public String toString() { return this.stateName; } }
The simple standard Java class shown above implements an isCase
method that will allow Groovy to switch on it. The following Groovy script uses this class and is able to successfully switch on the instance of State
.
#!/usr/bin/env groovy import dustin.examples.State State state = new State("Arkansas") State alabama = new State("Alabama") State arkansas = new State("Arkansas") State alaska = new State("Alaska") State arizona = new State("Arizona") State california = new State("California") State colorado = new State("Colorado") State connecticut = new State("Connecticut") print "The motto for the state of ${state.stateName} is '" switch (state) { case alabama : print "Audemus jura nostra defendere" break case alaska : print "North to the future" break case arizona : print "Ditat Deus" break case arkansas : print "Regnat populus" break case california : print "Eureka" break case colorado : print "Nil sine numine" break case connecticut : print "Qui transtulit sustinet" break default : print "<<State ${state.stateName} not found.>>" } println "'"
The output in the next screen snapshot indicates that the Groovy script is able to successfully switch on an instance of a State
object. The first command is using the "simple" example discussed earlier and the second command is using the example that needs to invoke State
's isCase(State)
method.
The beauty of this ability to have classes be "switchable" based on the implementation of an isCase()
method is that it allows more concise syntax in situations that otherwise might have required lengthy if
/else if
/else
constructs. It's preferable to avoid such constructs completely, but sometimes we run into them and the Groovy switch
statement makes them less tedious.
It is entirely possible with the Groovy switch
to have multiple switch options match the specified conditions. Therefore, it is important to list the case
statements in order of which match is preferred because the first match will be the one executed. The break
keyword is used in Groovy's switch
as it is in Java.
There is much more power in what the Groovy switch
supports. Some posts that cover this power include Groovy Goodness: The Switch Statement, Groovy, let me count the ways in which I love thee, and the Groovy documentation.
1 comment:
Yes i am really agree with all of your knowledge....and its really gr8 you have added coding here.....
Post a Comment