14

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
  • 732
  • 4
  • 11
  • 25

5 Answers5

8

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;
            }
   }        
Java42
  • 7,628
  • 1
  • 32
  • 50
  • 1
    See that was what I was avoiding, as I may as well just have two separate switches, one for each String :/ – Ciphor Mar 05 '13 at 12:13
  • 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. – Java42 Mar 05 '13 at 12:16
  • 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 :) – Ciphor Mar 05 '13 at 12:17
6

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.

Jere
  • 581
  • 2
  • 3
4

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.

Emerson Farrugia
  • 11,153
  • 5
  • 43
  • 51
2

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;
}
Andrea Ciccotta
  • 598
  • 6
  • 16
1

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

BackSlash
  • 21,927
  • 22
  • 96
  • 136
  • 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 Mar 05 '13 at 12:04
  • 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? – BackSlash Mar 05 '13 at 12:19
  • Well case "g" is like saying if(s1.equals("g") || s2.equals("g")) in my pseudo. – Ciphor Mar 05 '13 at 12:22
  • so your "or" in the switch is meaning that the two string must contain the same value? – BackSlash Mar 05 '13 at 12:23
  • No it's a logical OR if either of the Strings is "g" then the case "g" will be executed? – Ciphor Mar 05 '13 at 12:24
  • 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? – BackSlash Mar 05 '13 at 12:27
  • 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. – Ciphor Mar 05 '13 at 12:30
  • 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 :) – BackSlash Mar 05 '13 at 12:33
  • What I explained is what happens for that scenario, if either s1="a" or s2="a" you will still get the same behaviour :) – Ciphor Mar 05 '13 at 12:34
  • Yes, but also if s1=="g" or s2=="g" you said you would execute the "g" case, so what is the right one? – BackSlash Mar 05 '13 at 12:35
  • 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. – Ciphor Mar 05 '13 at 12:37
  • 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 :) – BackSlash Mar 05 '13 at 12:41
  • 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. – Ciphor Mar 05 '13 at 12:43
  • 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 Mar 05 '13 at 12:44
  • i.e. s1="a" s2="c", case="a"; s1="d" s2="b", case="b"; am i right? – BackSlash Mar 05 '13 at 12:45
  • 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 Mar 05 '13 at 12:46
  • "the kind of thing I want to achieve with a switch only." - thanks for your input though :) – Ciphor Mar 05 '13 at 12:57
  • Check my second update, you don't need to use a switch-case to do that – BackSlash Mar 05 '13 at 12:59
  • 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. – Ciphor Mar 05 '13 at 13:01
  • In this case, no, you cant do it with a single switch-case – BackSlash Mar 05 '13 at 13:03