Use string in switch case in java

JavaStringSwitch Statement

Java Problem Overview


I need to change the following if's to a switch-case while checking for a String, to improve the cyclomatic complexity.

String value = some methodx;
if ("apple".equals(value)) {
    method1;
}

if ("carrot".equals(value)) {
    method2;
}

if ("mango".equals(value)) {
    method3;
}

if ("orange".equals(value)) {
    method4;
}

But I am not sure what value I'm going to get.

Java Solutions


Solution 1 - Java

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...
}

Solution 2 - Java

Learn to use else.

Since value will never be equal to two unequal strings at once, there are only 5 possible outcomes -- one for each value you care about, plus one for "none of the above". But because your code doesn't eliminate the tests that can't pass, it has 16 "possible" paths (2 ^ the number of tests), of which most will never be followed.

With else, the only paths that exist are the 5 that can actually happen.

String value = some methodx;
if ("apple".equals(value )) {
    method1;
}
else if ("carrot".equals(value )) {
    method2;
}
else if ("mango".equals(value )) {
    method3;
}
else if ("orance".equals(value )) {
    method4;
}

Or start using JDK 7, which includes the ability to use strings in a switch statement. Course, Java will just compile the switch into an if/else like construct anyway...

Solution 3 - Java

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-else statements (as in cHao's answer).

Solution 4 - Java

To reduce cyclomatic complexity use a map:

Map<String,Callable<Object>> map = new HashMap < > ( ) ;
map . put ( "apple" , new Callable<Object> () { public Object call ( method1 ( ) ; return null ; } ) ;
...
map . get ( x ) . call ( ) ;

or polymorphism

Solution 5 - Java

Just to make concrete emory's answer, the executable code is the following :

  Map<String,Callable<USer>> map = new HashMap<String,Callable<User>>();
  map.put( "test" , new Callable<User> () { public User call (){ return fillUser("test" ); }} ) ;
  map.put( "admin" , new Callable<Utente> () { public Utente call (){  return fillUser("admin" ); }} ) ;

where user is a POJO, and then

  User user = map.get(USERNAME).call();

finally the called method is somewhere :

 private User fillUser(String x){		 
        User user = new User();
        // set something in User
        return user;
}

Solution 6 - Java

Java does not support Switch-case with String. I guess this link can help you. :)

Solution 7 - Java

Here is a possible pre-1.7 way, which I can't recommend:

public class PoorSwitch
{
	final static public int poorHash (String s) {
		long l = 0L;
		for (char c: s.toCharArray ()) {
			l = 97*l + c;
		}
		return (int) l;
	}
	
	public static void main (String args[])
	{
		String param = "foo";
		if (args.length == 1)
		{
			param = args[0];
		}
		// uncomment these lines, to evaluate your hash
		// test ("foo");
		// test ("bar");
		switch (poorHash (param)) {
			// this doesn't work, since you need a literal constant
			// so we have to evaluate our hash beforehand:
 			// case poorHash ("foo"): {
			case 970596: {
				System.out.println ("Foo!");
				break;
			}
			// case poorHash ("bar"): {
			case 931605: {
				System.out.println ("Bar!");
				break;
			}
			default: {
				System.out.println ("unknown\t" + param);
				break;
			}
		}
	}

	public static void test (String s)
	{
		System.out.println ("Hash:\t " + s + " =\t" + poorHash (s));
	}
}

Maybe you could work with such a trick in a generated code. Else I can't recommend it. Not so much that the possibility of a hash collision makes me worry, but if something is mixed up (cut and paste), it is hard to find the error. 931605 is not a good documentation.

Take it just as proof of concept, as curiosity.

Solution 8 - Java

We can apply Switch just on data type compatible int :short,Shor,byte,Byte,int,Integer,char,Character or enum type.

Solution 9 - Java

Evaluating String variables with a switch statement have been implemented in Java SE 7, and hence it only works in java 7. You can also have a look at how this new feature is implemented in JDK 7.

Solution 10 - Java

Java 8 supports string switchcase.

String type = "apple";

switch(type){
    case "apple":
       //statements
    break;
    default:
       //statements
    break; }

Solution 11 - Java

    String name,lname;
 name= JOptionPane.showInputDialog(null,"Enter your name");
   lname= JOptionPane.showInputDialog(null,"Enter your father name");
    if(name.equals("Ahmad")){
       JOptionPane.showMessageDialog(null,"welcome "+name);
    }
    if(lname.equals("Khan"))
   JOptionPane.showMessageDialog(null,"Name : "+name +"\nLast name :"+lname ); 
    
    else {
       JOptionPane.showMessageDialog(null,"try again " );
    } 
  }}

Solution 12 - Java

Not very pretty but here is another way:

String runFct = 
		queryType.equals("eq") ? "method1":
		queryType.equals("L_L")? "method2":
		queryType.equals("L_R")? "method3":
		queryType.equals("L_LR")? "method4":
			"method5";
Method m = this.getClass().getMethod(runFct);
m.invoke(this);

Solution 13 - Java

String value = someMethod();
switch(0) {
default:
    if ("apple".equals(value)) {
        method1();
        break;
    }
    if ("carrot".equals(value)) {
        method2();
        break;
    }
    if ("mango".equals(value)) {
        method3();
        break;
    }
    if ("orance".equals(value)) {
        method4();
        break;
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrandeepspView Question on Stackoverflow
Solution 1 - JavanickdosView Answer on Stackoverflow
Solution 2 - JavacHaoView Answer on Stackoverflow
Solution 3 - JavaSuragchView Answer on Stackoverflow
Solution 4 - JavaemoryView Answer on Stackoverflow
Solution 5 - Javam.piuntiView Answer on Stackoverflow
Solution 6 - JavaSunmit GirmeView Answer on Stackoverflow
Solution 7 - Javauser unknownView Answer on Stackoverflow
Solution 8 - JavaomarView Answer on Stackoverflow
Solution 9 - JavaDesta Haileselassie HagosView Answer on Stackoverflow
Solution 10 - JavaYashView Answer on Stackoverflow
Solution 11 - JavalatifaView Answer on Stackoverflow
Solution 12 - JavaConete CristianView Answer on Stackoverflow
Solution 13 - JavaTriquiView Answer on Stackoverflow