escutcheon

A Switch on String Idiom for Java

There is no way to perform a true switch on a String in Java. This seemingly trivial bit of functionality is common to many other languages, but has been frustratingly absent (to some) from Java. Various techniques have been offered that involve hashing, Maps, etc., but they are all overly complicated and generally not worth the trouble. With the advent of JDK 5.0 and its implementation of enum, a reasonably close approximation of this can be done using the following idiom. Create an enum using the default integer-based mapping, e.g.:

public enum Day
{
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY; 
}

Given this enum, the following switch statement could be used:

switch (Day.valueOf(str))
{
    case SATURDAY:              
    case SUNDAY:
        // weekend processing ...
        break;
    default:
        // weekday processing ...
}

Enum.valueOf() matches the given String to the actual enum name using the same basic hashcode() matching technique that earlier proposals have suggested; but with this idiom, all of that machinery is generated by the compiler and Enum implementation. The set of possible String values is also maintained in a more structured way when held in an enum.

Of course, the above suffers from the serious drawback that Enum.valueof() can throw an unchecked IllegalArgumentException or NullPointerException. The only real way to get around this issue is to create a new static method that absorbs these Exceptions and instead returns some default value:

public enum Day
{
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY,
    NOVALUE;

    public static Day toDay(String str)
    {
        try {
            return valueOf(str);
        } 
        catch (Exception ex) {
            return NOVALUE;
        }
    }   
}

Then the switch can be written to include a default clause that handles unexpected String values:

switch (Day.toDay(str))
{
    case SUNDAY:                
    case MONDAY:
    case TUESDAY:
        // etc ...
    default:
        // any non-Day value
}

While not quite as compact as the first technique, this is more robust and offers the possibility of performing case-insensitive switching also by calling, for example, toUpperCase() in the convert method after first checking the passed-in String for null.

» Posted: Friday, December 8, 2006 | Comments (67) | Permanent Link
fleuron

Comments

This was exactly the efficient solution I needed. Much thanks.

» Posted by Jake on March 8, 2007 11:06 PM

Just what I needed, too! Works beautifully.

» Posted by Zephron on March 10, 2007 04:46 PM

Helped a lot! Thanks.

» Posted by Hakan on April 22, 2007 09:23 AM

Excellent! I have been coding in PHP,C# and in my latest project in Java I was very surprised that Java don’t support String switch - this helped, thanks.

» Posted by Q on May 1, 2007 11:10 AM

Too much helpful..thanks buddy ..

» Posted by Anonymous on May 17, 2007 02:40 AM

This is great really, you’ve thought ahead for Chumps like me who would have been bitten later by the Exception.

My only suggestion is to ask if you could make the Sun smile at the top of the page! :-)

» Posted by Chump on June 19, 2007 04:00 PM

Nice and beatifully :)

» Posted by bronyte on June 26, 2007 12:06 PM

great, clear simple and smart !

» Posted by kassad on August 14, 2007 05:35 AM

Great job!! :]
thanks

» Posted by Pedro on September 28, 2007 11:55 PM

Don’t forget to uppercase the string before passing it into valueOf. Otherwise the user would have to enter all commands in uppercase… very Apple ][, but not particularly fun these days. :-)

» Posted by Trejkaz on October 8, 2007 07:46 PM

usefull ! thoose kind of posts are the ones that u wish when googling

» Posted by Lau on October 21, 2007 10:28 AM

This is truly like finding a diamond amongst sackfulls of coal. Thank you for sharing.

» Posted by JohnG on October 31, 2007 12:07 PM

Excellent! I applied this techniques in one of my Java programs today. Thanks

» Posted by pcdinh on December 31, 2007 01:41 PM

How do i use it with Strings like 0F, 0A etc?
I’m very new to java,,was working on C# :)

» Posted by Atul on February 9, 2008 03:41 AM

Should indicate that jdk 1.5 is compulsory. :)
But helpful tip

» Posted by Anonymous on February 15, 2008 11:19 AM

You rock, thanks for this.

» Posted by pd on March 13, 2008 08:33 PM

works
but what about case sensitive strings

» Posted by Anonymous on April 9, 2008 08:08 AM

It is case sensitive by default.

As mentioned in the entry itself, to make it case insensitive, logic would need to be included to ignore the case of the input string.

E.g., replace the try clause with the following so that “Sunday”, “sunday” or “SUNDAY” would all return Day.SUNDAY:

if(str != null)
{
return valueOf(str.toUpperCase());
}
else
{
return NOVALUE;
}
» Posted by winter on April 9, 2008 09:21 AM

Thanks a lot! This saved me much pain looking at all the if-else statements…

» Posted by Michal Filip on April 25, 2008 07:44 AM

After exploring various sites I found the exact solution to my problem here.
Thanks a lot!

» Posted by Himesh on May 19, 2008 02:57 AM

thank you very much!
The method is very good!

» Posted by onroad on June 4, 2008 09:26 AM

Very good. I’ve been programming in java for about 6 years now and i have always stayed away from switch and enums statements for this very limitation. You got to love the programming community. They make my life and job much easier

» Posted by Alao on July 30, 2008 04:40 PM

Thank you very much! Very nice solution

» Posted by Nitek on September 17, 2008 03:14 AM

Hey! Great job. It was the question that was asked in one of the interviews that I faced. Now I got the solution

» Posted by Bhoj Raj on September 30, 2008 03:02 AM

Dude, you rock!

» Posted by ylnotnull on October 28, 2008 02:05 PM

It’s really…..great of use.
Everyone should try……

» Posted by Vijay Raghuvanshi on November 11, 2008 04:45 AM

Thanks you so much for this helpful.

Work as well. ^^,

» Posted by Anonymous on January 3, 2009 09:30 PM

Quite useful! Thanks muchly. :)

» Posted by Anonymous on February 27, 2009 05:21 PM

Fantasic. I too was a little confused to find no select case (or switch) when moving from VB to Java. Life saver!

» Posted by Dan on March 26, 2009 12:24 AM

Interesting with this solution is that you can perform in the ofXxxx also some calculations.

maybe you have a range of values:


public enum Range
{
SMALL, MIDDLE, BIG,
NOVALUE;

public static Range toRange(Integer value)
{
if(value == null){
return NOVALUE;
} else if(value > 100){
return BIG;
} else if(value return SMALL;
} else {
return MIDDLE;
}
}
}


now you can handle also your range

switch (Range.toRange(myvalue))
{
case SMALL:
case MIDDLE:
case BIG:
// etc …
default:
// any non-Range value
}

» Posted by Arno Nyhm on March 27, 2009 12:32 PM

a great help…thanks

» Posted by Sumit on April 27, 2009 02:45 PM

AWESOME! Was just considering writing my own string handler for this and a few other things. One down!

THANKS FOR SHARING :)

» Posted by Angelo on May 18, 2009 08:11 AM

Excellent! Explanation

» Posted by PunnayyaSastryJandhyala on May 18, 2009 10:50 AM

Excellent solution, Exact thing I was looking for

Thanks,
Rohit

» Posted by Rohit on May 28, 2009 09:32 AM

how to convert 0-999 in string pls answer me?

» Posted by kenken on August 15, 2009 09:49 PM

Unfortunately, this suffers from the drawbacks of naming rules for enums. For example, I can’t check to see if something is equal to “set-port” or “—verbose-mode” because enum names cannot have “-” in them. Still a good solution for everything else.
Perhaps an Arraylist with all values stored in in, then an indexOf(String) performed in the switch?
Then you’d have to memorize the order, but it would let you use String literals, I think.

» Posted by Stilenx on October 5, 2009 02:37 AM

thnxs…

r|b|c

» Posted by RBC on October 6, 2009 07:19 AM

Thanks a lot, this is very helpful…. :)

» Posted by Anonymous on November 3, 2009 05:02 AM

This is a beautiful solution !!!

» Posted by Jagadheesan on November 6, 2009 04:32 PM

you saved our life

» Posted by sam&sarah on December 30, 2009 12:35 PM

Excellent tip - thanks!

» Posted by Mick on January 8, 2010 09:42 AM

Wow thanks man - this helped a ton! I hadnt been able to come up with a simpler solution

» Posted by drdan on February 16, 2010 09:38 PM

Note that this isn’t quite the same as switching on a string, as you’re still limited to having enum values which follow the rules of what constitutes a valid identifier. I’m doing a postfix expression calculator where “+” is used to denote addition, “-” subtraction, etc, but doing:

enum Operations
{
+, -, x, /;
}

Obviously does not work. As it stands I do:

switch (opRead.charAt(0))
{
case ‘+’:
….
}

But this has the drawback that if opRead is the string “+dsfkajflaskd” it will be treated like the string “+”. I can add verification code before the switch to ensure the token is only a single character, but then it’s really getting to the point I might as well just do:

if (opRead.equals(“+”))
….

etc.

» Posted by Adam on March 4, 2010 02:45 PM

At any rate, once Java 7 hits all this won’t matter as reports indicate that switches on strings will be added to the language.

http://code.joejag.com/2009/new-language-features-in-java-7/

» Posted by Adam on March 4, 2010 02:56 PM

niceeeee

» Posted by arsa on March 24, 2010 07:58 AM

Thansk for the soulution. Are there any way to check if the value in enum exists? I have some Strings and want to use a switch but not for all of the String, dont want to butt in all of the string in the Enum, just check if it exists and then use it in a switch.

/P

» Posted by P on March 25, 2010 07:18 AM

2010 and this post is still useful… great work. Thanks

» Posted by Anonymous on June 1, 2010 03:53 PM

thnx..very useful

» Posted by me on June 10, 2010 12:16 PM

Good and useful article…

As mentioned String switch may come soon…
http://blogs.sun.com/darcy/entry/project_coin_for_further_consideration

» Posted by Arvind on July 29, 2010 12:50 PM

Many thanks for your solution. It really helped me.

» Posted by James on August 27, 2010 11:19 AM

yuuupeeeee. THANKS, it worked for me too.

» Posted by kaa on September 14, 2010 11:12 AM

Great one….thanks a ton for publishing

» Posted by Jeron on December 9, 2010 01:50 AM

very thanks….
this is what i was searching for

» Posted by Anonymous on December 23, 2010 07:35 AM

Great post!
I am c# developer and i am exploring JSP.I came across this issue of switch with my jsp project.
How come the number one programming language Java cannot accept other data types beside int in switch.
In c# switch accept mainly any data type.

» Posted by Talley on February 7, 2011 03:34 PM

Great work. It was very helpful for me senice I was working on programming ass. which asked the user to enter a color then the shape will be colored as the user want.
Thanks alot,

» Posted by Mask on February 8, 2011 11:33 PM

it Helped a lot! Thanks.

» Posted by naga on March 25, 2011 06:56 AM

Simply Superb! Thanks.

» Posted by Rajkumar.M on March 25, 2011 07:01 AM

tnx man =)
good stuff

» Posted by smokes on April 27, 2011 05:50 PM

Silly post. If you find yourself in need of switching on String, you have either made the wrong choice of language or are writing poor code.

» Posted by Randomizer on June 11, 2011 10:33 AM

thanks man. it helps a lot. :)

» Posted by gydio on July 23, 2011 01:48 PM

Good Example and very well explained.You can also see some advanced example of Enum in Java here.

» Posted by Rajiv on December 1, 2011 08:38 PM

How to handle switch statement for two keyword like “Hello World” together.

» Posted by Jenny on December 4, 2011 11:56 PM

Great!

» Posted by Sathya Moorthi K on December 24, 2011 12:58 PM

Really good,thanks a lot.

» Posted by mohan on January 19, 2012 12:40 AM

Excellent solution to handle enum exception.

» Posted by Murali on January 27, 2012 02:47 PM

excellent piece of code.

» Posted by Edominguez on March 1, 2012 11:38 AM

If you like to compare different text from enum names

Just consider that each enum is like a small class, so you an define also constructors as you like. Have status variables/fields etc

You can define:

… PLUS(“+”), MINUS(“-“)

And the compare this values. You can also define more parameters for constructor for an enum SunTime like

SUNRISE(“sunrise”, “sun-rise”, “sun-rice”)

And the use the SunTime(string names…) to get an list o parameters to save in a field or a static field etc

» Posted by Arno.Nyhm on April 19, 2012 11:09 AM