views:

20467

answers:

9

Simple question -- why can't I switch on a String in Java, and as far as anyone knows, is this functionality going to be put into a later Java version?

EDIT: If someone can point me to an article, or themselves explain why I can't do this, as in, the technical way Java's switch statement works, it would be most appreciated.

UPDATE: Along the lines of the post made by @erickson, this feature is confirmed to be implemented in Java 7.

+33  A: 
erickson
It might be faster to just use If-Else-If instead of a hash for a string based switch. I have found dictionaries to be quite expensive when only storing a few items.
Jonathan Allen
An if-elseif-elseif-elseif-else might be faster, but I'd take the cleaner code 99 times times out of 100. Strings, being immutable, cache their hash code, so "computing" the hash is fast. One would have to profile code to determine what benefit there is.
erickson
The reason given against adding switch(String) is that it wouldn't meet the performance guarantees expects from switch() statements. They didn't want to "mislead" developers. Frankly I don't think they should guarantee the performance of switch() to begin with.
Gili
Excellent answer. +1
JesperE
+3  A: 

Switches based on integers can be optimized to very efficent code. Switches based on other data type can only be compiled to a series of if() statements.

For that reason C & C++ only allow switches on integer types, since it was pointless with other types.

The designers of C# decided that the style was important, even if there was no advantage.

The designers of Java apparently thought like the designers of C.

James Curran
Switches based on any hashable object may be implemented very efficiently using a hash table – see .NET. So your reason isn't completely correct.
Konrad Rudolph
Yeah, and this is the thing I don't understand. Are they afraid hashing objects will, in the long run, become too expensive?
Alex Beardsley
@Nalandial: actually, with a little effort on the part of the compiler, it's not expensive at all because when the set of strings is known, it's pretty easy to generate a perfect hash (this isn't done by .NET, though; probably not worth the effort, either).
Konrad Rudolph
martinatime
+3  A: 

Java can't switch on objects, only standard data types.

This is a discussion at java.net regarding requests to add the ability to switch on objects in future versions: http://forums.java.net/jive/thread.jspa?threadID=595

Right now the answer is unknown on whether or not it will be added in the future.

Jeremiah
+17  A: 

If you have a place in your code where you can switch on a String, then it may be better to refactor the String to be an enumeration of the possible values, which you can switch on. Of course, you limit the potential values of Strings you can have to those in the enumeration, which may or may not be desired.

Of course your enumeration could have an entry for 'other', and a fromString(String) method, then you could have

ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
   case MILK: lap(); break;
   case WATER: sip(); break;
   case BEER: quaff(); break;
   case OTHER: 
   default: dance(); break;
}
JeeBee
This technique also lets you decide on issues such a case insensitivity, aliases, etc. Instead of depending on a language designer to come up with the "one size fits all" solution.
Darron
Agree with JeeBee, if you are switching on strings probably need an enum . The string usually represents something going to an interface (user or otherwise) that may or not change in the future so better replace it with enums
hhafez
See http://www.xefer.com/2006/12/switchonstring for a nice write-up of this method.
David Schmitt
+1  A: 

Reminds me of this thread : http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/ddee6c336894e00d

Ah, Jon Skeet is already there! (in 2001...)
PhiLho
+2  A: 

James Curran succinctly says: "Switches based on integers can be optimized to very efficent code. Switches based on other data type can only be compiled to a series of if() statements. For that reason C & C++ only allow switches on integer types, since it was pointless with other types."

My opinion, and it's only that, is that as soon as you start switching on non-primitives you need to start thinking about "equals" versus "==". Firstly comparing two strings can be a fairly lengthy procedure, adding to the performance problems that are mentioned above. Secondly if there is switching on strings there will be demand for switching on strings ignoring case, switching on strings considering/ignoring locale,switching on strings based on regex.... I would approve of a decision that saved a lot of time for the language developers at the cost of a small amount of time for programmers.

DJClayworth
+1  A: 

Beside the above good arguments, I will add that lot of people today see switch as an obsolete remainder of procedural past of Java (back to C times).

I don't fully share this opinion, I think switch can have its usefulness in some cases, at least because of its speed, and anyway it is better than some series of cascading numerical else if I saw in some code...

But indeed, it is worth looking at the case where you need a switch, and see if it cannot be replaced by something more OO. For example enums in Java 1.5+, perhaps HashTable or some other collection (sometime I regret we don't have (anonymous) functions as first class citizen, as in Lua — which doesn't have switch — or JavaScript) or even polymorphism.

PhiLho
+1  A: 

will be added in version 7 of Java (February 2010).

A: 

sounds great! bring us more convenient

Sharl