Java switch statement to handle two variables?

59,895

Solution 1

Using a single switch per your requirement is not possible. This is as close as your going to get using Java.

    switch (s1)  {
        case "a":  doAC(); break;
        case "b":  doBD(); break;
        default:
            switch(s2) {
                case "c":  doAC(); break;
                case "d":  doBD(); break;
            }
   }        

Solution 2

Have you considered not using the switch statement but instead using lookup tables?

public class MyClass {
    private static final Map<String, Integer> valuesMap;

    static {
         Map<String,Integer> aMap = new HashMap<>();
         aMap.put("a", 0);
         aMap.put("b", 1);
              ..... rest .....
         valuesMap = Collections.unmodifiableMap(aMap);
    }

    public void foo()
    {
       int s1Value = 0;
       int s2Value = 0;

       String s1 = "a";
       String s2 = "g";
       if( valuesMap.containsKey(s1) )
       {
          s1Value = valuesMap.get(s1);
          s2Value = s1Value;
       }
       else if( valuesMap.contansKey(s2) )
       {
          s1Value = valuesMap(s2);
          s2Value = s1Value;
       }
    }
}

If you needed a different set of values of the s2Value then you could construct a second map to pull those from.

Since you wanted to use a switch I take that to mean the possible candidates and values is a fixed, known at development time list, so using a statically initialized map like this shouldn't be an issue.

Solution 3

The only way to do that with a single switch is to first merge the two values, finding the one with the highest precedence, and applying the switch to the result. In your example, the minimum of s1 and s2, and switching on the result.

Since "a" through "g" are an example, you'll need to have some meaningful way to rank the real values first.

Solution 4

You can do what you want without using a switch, simply by writing that:

s1value = s1.charAt(0)-'a'; //returns 0 if s1value="a", 1 if s1value="b", etc.

What i don't completely understand is what do you mean with

(s1 || s2)

Do you want to do something like this?

  int s1Value = 0;
  int s2Value = 0;

  String s1 = "g";
  String s2 = "a";

  char s1char = s1.charAt(0);
  char s2char = s2.charAt(0);
  int myChar = Math.max(s1char, s2char);
  s1Value = s2Value = myChar - 'a';

UPDATE

In comments, you wrote:

s1="g" and s2="g" before entering the switch, then the only case that will evaluate to true is case "g" and so both s1Value and s2Value will become 6 and then exit the switch.

So, i think you're saying that s1 and s2 are initialized with the same value, so:

  int s1Value = 0;
  int s2Value = 0;

  String s1 = "g";
  String s2 = "g";

  char s1char = s1.charAt(0);
  s1Value = s2Value = s1char - 'a'; //s1Value = s2Value = 6

This should do what you want

UPDATE 2

with s1="a" and s2="d" we consider case "a", with s1="c" and s2="b" we consider case "b"

Try this:

  int s1Value = 0;
  int s2Value = 0;

  String s1 = "g";
  String s2 = "a";

  char s1char = s1.charAt(0);
  char s2char = s2.charAt(0);
  int myChar = Math.min(s1char, s2char);
  s1Value = s2Value = myChar - 'a';

It should do the trick, test it and let me know if it works

Solution 5

Languages like scala&python give to you very powerful stuff like patternMatching, unfortunately this is still a missing-feature in Java...

but there is a solution (which I don't like in most of the cases), you can do something like this:

final int s1Value = 0;
final int s2Value = 0;
final String s1 = "a";
final String s2 = "g";

switch (s1 + s2 + s1Value + s2Value){
    case "ag00": return true;
    default: return false;
}
Share:
59,895
Ciphor
Author by

Ciphor

Updated on July 09, 2022

Comments

  • Ciphor
    Ciphor almost 2 years

    I'm looking for a way to handle two strings using a single switch, I'm thinking this impossible within Java.

    Here is some pseudo code of the kind of thing I want to achieve with a switch only.

        int s1Value = 0;
        int s2Value = 0;
        String s1 = "a";
        String s2 = "g";
        switch (s1 || s2) {
             case "a": s1value = 0; s2value = 0; break;
             case "b": s1value = 1; s2value = 1; break;
             case "c": s1value = 2; s2value = 2; break;
             case "d": s1value = 3; s2value = 3; break;
             case "e": s1value = 4; s2value = 4; break;
             case "f": s1value = 5; s2value = 5; break;
             case "g": s1value = 6; s2value = 6; break;
        }
    
  • Ciphor
    Ciphor about 11 years
    No nothing to do with traversing through the String, I simply want to check in each case whether or not either s1 OR s2 is true and then perform some statements if it is.
  • Ciphor
    Ciphor about 11 years
    See that was what I was avoiding, as I may as well just have two separate switches, one for each String :/
  • Java42
    Java42 about 11 years
    Two seperate switches can causes bugs in your code becuase doAC() or doBD() will be called twice. You need to use nested switches as I have indicated.
  • Ciphor
    Ciphor about 11 years
    If it is not possible like you say, I'll just have to dream of the day when I can use a boolean expression as the switch statement :)
  • BackSlash
    BackSlash about 11 years
    s1 and s2 cannot be true or false, as they are Strings and not booleans, so basically you can't check if a string is true or false. Tell me, when should your string be true, and when should it be false?
  • Ciphor
    Ciphor about 11 years
    Well case "g" is like saying if(s1.equals("g") || s2.equals("g")) in my pseudo.
  • BackSlash
    BackSlash about 11 years
    so your "or" in the switch is meaning that the two string must contain the same value?
  • Ciphor
    Ciphor about 11 years
    No it's a logical OR if either of the Strings is "g" then the case "g" will be executed?
  • BackSlash
    BackSlash about 11 years
    and what is happening if either of the string is "a"? use your example and try to explain it to me, s1="g" and s2="a", what would happen and why?
  • Ciphor
    Ciphor about 11 years
    Ok so, it would first test for case "a" or in long form if(s1.equals("a") || s2.equals("a")) which evaluates to true as s2 = "a" then it would assign the value 0 to both s1Value and s2Value and exit the switch.
  • BackSlash
    BackSlash about 11 years
    Yes, but i asked you what does it happen if s1="g" and s2="a"? :) sorry if i'm continuing to ask you but i'm trying to understand your problem :)
  • Ciphor
    Ciphor about 11 years
    What I explained is what happens for that scenario, if either s1="a" or s2="a" you will still get the same behaviour :)
  • BackSlash
    BackSlash about 11 years
    Yes, but also if s1=="g" or s2=="g" you said you would execute the "g" case, so what is the right one?
  • Ciphor
    Ciphor about 11 years
    If s1="g" and s2="g" before entering the switch, then the only case that will evaluate to true is case "g" and so both s1Value and s2Value will become 6 and then exit the switch.
  • BackSlash
    BackSlash about 11 years
    check my update, if s1 and s2 are equal before entering the switch everything is a lot easier, in your example you initialized s1 and s2 with different values. If i misunderstood another time, try to be more clear to make me understand better your problem :)
  • Ciphor
    Ciphor about 11 years
    Here's another example: s1="f" and s2="d" case "d" would be checked first and evaluate to true because s2="d" and then s1Value and s2Value are assigned the value 3 and then we exit the switch.
  • BackSlash
    BackSlash about 11 years
    so you're checking wich of the 2 strings has the lower character between a,b,c,d,e,f,g, and then updating s1Value and s2Value?
  • BackSlash
    BackSlash about 11 years
    i.e. s1="a" s2="c", case="a"; s1="d" s2="b", case="b"; am i right?
  • Ciphor
    Ciphor about 11 years
    Well...in this example, you could say it has those semantics, but think of it more generally...say the letters were not in order and for example case "hello" assigns 1 to s1Value and 34 to s2Value :) And yes you are right with that :)
  • Ciphor
    Ciphor about 11 years
    "the kind of thing I want to achieve with a switch only." - thanks for your input though :)
  • BackSlash
    BackSlash about 11 years
    Check my second update, you don't need to use a switch-case to do that
  • Ciphor
    Ciphor about 11 years
    I know you don't, to be honest I can achieve it all with if/else but I wanted to know if Java had the capabilities to achieve what I wanted using a switch.
  • BackSlash
    BackSlash about 11 years
    In this case, no, you cant do it with a single switch-case