Hey guys. I'm pretty sure I'm a simple fix away from completing one of my assignments but I'm having a little bit of a problem with my switch case. I just want to see if it's possible to have a blank space in a string switch case because my code is not doing what I want it to do. This is my code for that portion.
switch(ans){
case "Italy":
System.out.println("Thank you!");
it++;
break;
case "Costa Rica":
System.out.println("Thank you!");
cr++;
break;
case "Pax Bisonica":
System.out.println("Thank you!");
pb++;
break;
case "Ghana":
System.out.println("Thank you!");
gh++;
break;
If anyone can help me with the Costa Rica and Pax Bisonica cases that would be great!
design - What is the benefit of switching on Strings in Java 7? - Software Engineering Stack Exchange
java - Why can't I use switch statement on a String? - Stack Overflow
Use string in switch case in java - Stack Overflow
The Switch vs. If-then-else statements - Java - Code with Mosh Forum
Videos
As far as I can tell, the question is why wrapping String constants into enum hasn't been considered sufficient to cover the needs of language users. This has been addressed in the official feature proposal announced at JDK 7 (project Coin) mailing list.
Per my reading of the proposal, alternative of using enums has been dismissed on the ground that it introduces types bloat. For your convenience, relevant part of the proposal is quoted below, with the statement addressing enums quoted in bold:
MAJOR ADVANTAGE: What makes the proposal a favorable change?
More regular coding patterns can be used for operations selected on the basis of a set of constant string values; the meaning of the new construct should be obvious to Java developers.
MAJOR BENEFIT: Why is the platform better if the proposal is adopted?
Potentially better performance for string-based dispatch code.
MAJOR DISADVANTAGE: There is always a cost.
Some increased implementation and testing complexity for the compiler.
ALTERNATIVES: Can the benefits and advantages be had some way without a language change?
No; chained if-then-else tests for string equality are potentially expensive and introducing an enum for its switchable constants, one per string value of interest, would add another type to a program without good cause...
Apart from making the code more readable, there are potential performance gains relative to if/else if comparisons. Whether the change is worthwhile depends on how many comparisons you would be making. A string switch will be emitted as two separate switch instructions. The first operates on hash codes, so it tends to be a lookupswitch, ultimately yielding O(log n) complexity. The second is always a perfect O(1) tableswitch, so the combined complexity is still O(log n). A single, linear chain of if/else if statements would give slightly worse O(n) complexity.
If you're comparing more than, say, three strings, then a switch is probably more readable and compact. It will likely perform better, though you are unlikely to notice a difference unless you are doing a large number of comparisons on a hot code path.
Switch statements with String cases have been implemented in Java SE 7, at least 16 years after they were first requested. A clear reason for the delay was not provided, but it likely had to do with performance.
Implementation in JDK 7
The feature has now been implemented in javac with a "de-sugaring" process; a clean, high-level syntax using String constants in case declarations is expanded at compile-time into more complex code following a pattern. The resulting code uses JVM instructions that have always existed.
A switch with String cases is translated into two switches during compilation. The first maps each string to a unique integer—its position in the original switch. This is done by first switching on the hash code of the label. The corresponding case is an if statement that tests string equality; if there are collisions on the hash, the test is a cascading if-else-if. The second switch mirrors that in the original source code, but substitutes the case labels with their corresponding positions. This two-step process makes it easy to preserve the flow control of the original switch.
Switches in the JVM
For more technical depth on switch, you can refer to the JVM Specification, where the compilation of switch statements is described. In a nutshell, there are two different JVM instructions that can be used for a switch, depending on the sparsity of the constants used by the cases. Both depend on using integer constants for each case to execute efficiently.
If the constants are dense, they are used as an index (after subtracting the lowest value) into a table of instruction pointers—the tableswitch instruction.
If the constants are sparse, a binary search for the correct case is performed—the lookupswitch instruction.
In de-sugaring a switch on String objects, both instructions are likely to be used. The lookupswitch is suitable for the first switch on hash codes to find the original position of the case. The resulting ordinal is a natural fit for a tableswitch.
Both instructions require the integer constants assigned to each case to be sorted at compile time. At runtime, while the O(1) performance of tableswitch generally appears better than the O(log(n)) performance of lookupswitch, it requires some analysis to determine whether the table is dense enough to justify the space–time tradeoff. Bill Venners wrote a great article that covers this in more detail, along with an under-the-hood look at other Java flow control instructions.
Before JDK 7
Prior to JDK 7, enum could approximate a String-based switch. This uses the static valueOf method generated by the compiler on every enum type. For example:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}
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;
}
Java (before version 7) does not support String in switch/case. But you can achieve the desired result by using an enum.
private enum Fruit {
apple, carrot, mango, orange;
}
String value; // assume input
Fruit fruit = Fruit.valueOf(value); // surround with try/catch
switch(fruit) {
case apple:
method1;
break;
case carrot:
method2;
break;
// etc...
}
Everybody is using at least Java 7 now, right? Here is the answer to the original problem:
String myString = getFruitString();
switch (myString) {
case "apple":
method1();
break;
case "carrot":
method2();
break;
case "mango":
method3();
break;
case "orange":
method4();
break;
}
Notes
- The case statements are equivalent to using
String.equals. - As usual, String matching is case sensitive.
- According to the docs, this is generally faster than using chained
if-elsestatements (as in cHao's answer).