Case insensitive matching in Java switch-case statement - java

I was wondering if there is a way to perform case insensitive match in java switch case statement. the default implementation is case sensitive. Please see the example below.
public class SwitchCaseTest {
/**
* #param args
*/
public static void main(String[] args) {
switch ("UPPER") {
case "upper" :
System.out.println("true");
break;
default:
System.out.println("false");
break;
}
}
}
So above statement returns false as output. And i am trying make it work for case-insensitive match like String.equalsIgnoreCase() would do. I tried to convert both the string literal to lower case and then compare. but was unable to do so.

If you want to do that: just make sure the input data is in all lowercase, and use lowercase cases...
switch ("UPPER".toLowerCase()) {
case "upper" :
....
Localization issues
Also, the ages old issue of localization strikes again, and plagues this thing too... For example, in the Turkish Locale, the uppercase counterpart of i is not I, but İ... And in return, the I is not transformed to i, but a "dotless i": ı. Don't underestimate this, it can be a deadly mistake...

You try making everything uppercase or lowercase
String str = "something".toUpperCase();
switch(str){
case "UPPER":
}
or
String str = "something".toLowerCase();
swtich(str){
case "lower":
}
or even better use enum (note this is only possible from Java 7)
enum YourCases {UPPER1, UPPER2} // cases.
YourCases c = YourCases.UPPER1; // you will probably get this value from somewhere
switch(c){
case YourCases.UPPER1: ....
break;
case YourCases.UPPER2: ....
}

When using a switch statement you must use "break;" for it to exit the statement, so simply use two cases, one without a break.
switch(choice)
{
case 'I':
case 'i':
//Insert a name
System.out.print("Insert a name to add to the list: ");
input.nextLine();
name = input.nextLine();
nameList.insert(name);
System.out.println();
break;
This way, if either "I" or "i" are entered, both cases will have the same outcome.

try
switch ("UPPER".toUpperCase()) {
case "UPPER" :

To avoid having to use the case expression to verify if it is lowercase or uppercase, I recommend that you use the following:
String value = String.valueOf(userChoice).toUpperCase();
This helps to make the conversion of lowercase to uppercase before doing the evaluation in the switch case.

Related

using method in switch case statements

I was wondering if you could use methods such as 'contains()' in the case of a switch case. I am trying to make the following if statements into a switch case:
String sentence;
if(sentence.contains("abcd")){
// do command a
}
else if(sentence.contains("efgh")){
// do command b
}
else if(sentence.contains("ijkl")){
// do command c
}
else{
//do command d
}
Thank you very much for your help.
actually you can change this if into switch, but its kinda unreadable:
final String sentence;
int mask = sentence.contains("abcd") ? 1 : 0;
mask |= sentence.contains("efgh") ? 2 : 0;
mask |= sentence.contains("ijkl") ? 4 : 0;
switch (mask) {
case 1:
case 1 | 2:
case 1 | 4:
case 1 | 2 | 4:
// do command a
break;
case 2:
case 2 | 4:
// do command b
break;
case 4:
// do command c
break;
default:
// do command d
}
}
No, because the case constant must be either:
A constant expression
Or the name of an enumerator of the same type as the switch expression.
A method call is neither of these.
From the Java Language Specification, section 14.11: The switch statement:
Every case label has a case constant, which is either a constant expression or the name of an enum constant.
Yes, you can get an equivalent bit of code to work using the switch statement assuming you are using JDK 7 or higher. JDK 7 introduced the ability to allow String objects as the expression in a switch statement. This generally produces more efficient bytecode compared to a chain of if-then-else statements invoking the equals method.
String pattern;
String sentence;
if (sentence.contains(pattern))
{
switch (pattern)
{
case "abcd":
// do command a
break;
case "efgh":
// do command b
break;
case "ijkl":
// do command c
break;
default:
// do command d
break;
}
}
Do note however that this only works because the contains method expects a String object, and String objects are now valid inside switch statements. You can't generalize this to work with objects of an arbitrary type.
no you cant. case statements can only compare the values of the thing being "switch"ed. Infact, java only 'recently' started supporting switch statements on Strings, since they are objects and not primitive. In general, switch statements will work only on primitives. The only exception to that, as far as im aware, is for Strings

Trouble with switch statements?

I am just trying to write a program that generates a random year between 2000 and 2010, then reads off a space exploration fact that occurred in that year.
This is the code that I have written, however when I run it, no matter what year is generated, it just prints the last case (2010). How do I fix this?
import java.util.Random;
public class SpaceExploration {
public static void main(String[] args) {
int year =(int)(Math.random()*11) + 2000;
String eventString = "";
switch (year) {
case 2000: eventString = "2000: First spacecraft orbits an asteroid";
case 2001: eventString = "2001: First spacecraft lands on asteroid";
case 2002: eventString = "2002: N/A";
case 2003: eventString = "2003: Largest infrared telescope released";
case 2004: eventString = "2004: N/A";
case 2005: eventString = "2005: Spacecraft collies with comet";
case 2006: eventString = "2006: Spacecraft returns with collections from a comet";
case 2007: eventString = "2007: N/A";
case 2008: eventString = "2008: Kepler launched to study deep space";
case 2009: eventString = "2009: N/A";
case 2010: eventString = "2010: SpaceX sucessfully sends spacecraft to orbit and back";
}
System.out.println(eventString);
}
}
You need to add break statement after each case else after finding matching case it will just execute all cases until it finds break or the end which in your case is 2010.
Your code should look like:
switch (year) {
case 2000:
eventString = "2000: First spacecraft orbits an asteroid";
break;
case 2001:
eventString = "2001: First spacecraft lands on asteroid";
break;
...
notice the break after every case.
The other answers are correct, you have to introduce the break after every case.
In general you should also add the case default case and add some console output to make sure you're software is working as intended.
An alternative solution would be to use a HashMap:
Map<Integer, String> map = new HashMap<>();
map.put(2010, 2010: SpaceX sucessfully sends spacecraft to orbit and back);
...
String eventString = map.get(year);
Like this, you would enter the switch statement at the year you're providing and then fall-through all the way to the last case. That way, your eventString always contains the value of year 2010. To prevent this, simply add a break statement in each case.
Break is the keyword which is use to jump from the loop (while,do-while and for) and switch statements, break should be use when certain conditions matches and you want to come out from the loops or switch.
while(true){
if(true) {
break ; // when you want to get out from the loop
}
}
and for switch statements you should use break statements to get out from the loop.
What you have experienced is a feature of the switch statement called 'fall through'.
Although usually one uses the break variant (which makes sense in most cases) there are some applications to be executed in a defined order, falling through some cases in a waterfally manner. Look at the application below(link):
Another point of interest is the break statement. Each break statement terminates the enclosing switch statement. Control flow continues with the first statement following the switch block. The break statements are necessary because without them, statements in switch blocks fall through: All statements after the matching case label are executed in sequence, regardless of the expression of subsequent case labels, until a break statement is encountered. The program SwitchDemoFallThrough shows statements in a switch block that fall through. The program displays the month corresponding to the integer month and the months that follow in the year:
public class SwitchDemoFallThrough {
public static void main(String[] args) {
java.util.ArrayList<String> futureMonths =
new java.util.ArrayList<String>();
int month = 8;
switch (month) {
case 1: futureMonths.add("January");
case 2: futureMonths.add("February");
case 3: futureMonths.add("March");
case 4: futureMonths.add("April");
case 5: futureMonths.add("May");
case 6: futureMonths.add("June");
case 7: futureMonths.add("July");
case 8: futureMonths.add("August");
case 9: futureMonths.add("September");
case 10: futureMonths.add("October");
case 11: futureMonths.add("November");
case 12: futureMonths.add("December");
break;
default: break;
}
if (futureMonths.isEmpty()) {
System.out.println("Invalid month number");
} else {
for (String monthName : futureMonths) {
System.out.println(monthName);
}
}
}
}
So if you want to get all space exploration facts that occurred in that year and later, you can omitt the breaks.

How to do a case with multiple conditions?

In the 1 month experience I've had with any programming language, I've assumed that switch case conditions would accept anything in the parenthesis as a boolean checking thingamajig, ie
these:
|| && < >
Know what I mean?
something like
char someChar = 'w';
switch (someChar) {
case ('W' ||'w'):
System.out.println ("W or w");
}
Sadly, doesn't seem to work that way. I can't have boolean checking in switch case.
Is there a way around it?
By the way, terribly sorry if I'm sounding confusing. I don't quite know the names for everything in this language yet :X
Any answers appreciated
You can achieve an OR for cases like this:
switch (someChsr) {
case 'w':
case 'W':
// some code for 'w' or 'W'
break;
case 'x': // etc
}
Cases are like a "goto" and multiple gotos can share the same line to start execution.
You can do -
switch(c) {
case 'W':
case 'w': //your code which will satisfy both cases
break;
// ....
}
Every case is normally followed by a "break;" statement to indicate where execution should terminate. If you omit the "break;", then execution will continue. You can use this to support multiple cases which should be handled the same way:
char someChar = 'w';
{
case 'W':
// no break here
case 'w':
System.out.println ("W or w");
break;
}
Switch cases are branches for alternative evaluations of a given expression. The expression is given in the switch parenthesis and can be byte, short, char, and int data types.
The body of a switch statement is known as a switch block. A statement
in the switch block can be labeled with one or more case or default
labels. The switch statement evaluates its expression, then executes
all statements that follow the matching case label.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
For an alternate to switch statement(multiple if conditions), I think the best solution will be using an enum. For example: Consider the case below:-
public enum EnumExample {
OPTION1{
public double execute() {
Log.info(CLASS_NAME, "execute", "The is the first option.");
return void;
}
},
OPTION2{
public double execute() {
Log.info(CLASS_NAME, "execute", "The is the second option.");
return void;
}
},
OPTION3{
public double execute() {
Log.info(CLASS_NAME, "execute", "The is the third option.");
return void;
};
public static final String CLASS_NAME = Indicator.class.getName();
public abstract void execute();
}
The above enum can be used in the following fashion:
EnumExample.OPTION1.execute();
Hopefully this helps you guys.

How to implement a special character(?) as an option in a Switch of type 'char'?

I am attempting to use a Switch statement to use as a menu interface, and I was wondering how I can include a "help" option, which is triggered by the user having input a '?' symbol.
But as the Switch is accepting type 'char', I am not sure how this is possible.
Could you please point me in the right direction?
Here is my non-compiling code so far:
private char readChoice()
{ System.out.print("Choice (a/b/c/s/?/x): ");
return In.nextLine().toLowerCase().charAt(0); }
private void execute(char choice)
{ switch (choice)
{ case 'a': routes.show(); break;
case 'b': customers.book(routes); break;
case 'c': customers.show(); break;
case 's': routes.showSchedule(); break;
case '\?': showHelp(); break;
case 'x': break; }}
private String showHelp()
{ String helpText = " A/a Show bookings by route\n";
helpText += " B/b Book a trip\n";
helpText += " C/c Show bookings by customer\n";
helpText += " ? Show choices\n";
helpText += " X/x Exit\n";
return helpText; }
One other question, is there a more suitable way to implement the 'Exit' option, rather than just having a break after an 'x' is input?
Thank you for taking the time to read through my question.
There's nothing special about the question mark character within the Java language. You don't need to escape it - it's not like in a regular expression. Just use:
case '?': showHelp(); break;
See JLS section 3.10.4 for the characters you do need to escape (and the escape sequences available).
EDIT: As per the comments, the problem is with the showHelp() method, which builds a string but doesn't return it. You probably want something like:
private String showHelp() {
out.println(" A/a Show bookings by route");
out.println(" B/b Book a trip");
out.println(" C/c Show bookings by customer");
out.println(" ? Show choices");
out.println(" X/x Exit");
}
... for a suitable value of out.
(As an aside, your bracing style is odd and I for one find it pretty hard to read. There are two common bracing styles in Java - the one I showed in the above code, and the "brace on a separate line at the same indentation as the closing brace" version. For the sake of others who might read your code, it's probably worth adopting one of those common styles.)
There is no need to escape the ? in a char:
case '?': showHelp(); break;
is there a more suitable way to implement the 'Exit' option, rather than just having a break after an 'x' is input?
It if fine but it would work the same way if you removed it. What would possibly make more sense would be something like:
case 'x': break;
default: showErrorMessage();
So if the user enters an unauthorised character, you let him know.
You do not need to escape the '?' in a char. Also - you're not doing anything with the String you construct and return from showHelp() currently. You would need to do something with that like:
String message;
switch(choice) {
//.. stuff ommitted
case '?': message = showHelp(); break;
Or you should display the message within showHelp.

java switch statement with multiple cases and case ranges

I wanted to find a way to do this in java 6, but it doesn't exist:
switch (c) {
case ['a'..'z']: return "lower case" ;
There was a proposal to add this to the java language some time ago: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000213.html, has anything materialized in java 7?
What are other ways to rewrite this code in java 6, that would read more like a switch/case:
if (theEnum == MyEnum.A || theEnum == MyEnum.B){
}else if(), else if, else if...
You could do something like:
switch (c) {
case 'a':
case 'b':
case 'c':
//...
doSomething();
break;
}
The simplest thing would be:
if (Character.isLowerCase(c)){
return "lowercase";
}
Which will also work with á ö and the sort
How about this?
if(c>='a' && c<='z')
return "lower case";
To the first part, one options for strings
if(c.equals(c.toLowerCase())) return "lower case";
To the second part, you can use switch with enums....
switch(theEnum){
case A:
case B:
break;
case C:
break;
...
}
Or:
if (inRange(c, 'a', 'z')) {
...
}
or use a regex like normal, or a map, or...
With regards to your enum expression, it depends on what you're actually doing, but it might just be a map with implementations or values.

Categories

Resources