6

I have code where what a switch statement is testing for depends on an array variable:

String shuff = Import.shuffle();
String[] form = new String[95];
for(int i = 0; i < 95; i++)
{
    form[i] = Format.shuffle(shuff, i);
}
switch(str)
{
case "a":
    x = 6;
    break;
case "b":
    x = 16; 
    break;
case "c":
    x = 23;
    break;
//So on and so forth
}

What I want to do is take the array form[] and use it as the case:

String shuff = Import.shuffle();
String[] form = new String[95];
for(int i = 0; i < 95; i++)
{
    form[i] = Format.shuffle(shuff, i);
}
switch(str)
{
case form[0]:
    x = 6;
    break;
case form[1]:
    x = 16; 
    break;
case form[2]:
    x = 23;
    break;
//So on and so forth
}

But when I try this, it gives the error "case expressions must be constant expressions". Two options to solve this come to mind, but I don't know how to do either. 1. use the array in the switch case somehow 2. use some sort of method that would look like this...

String shuff = Import.shuffle();
String[] form = new String[95];
for(int i = 0; i < 95; i++)
{
    form[i] = Format.shuffle(shuff, i);
}
switch(str)
{
case form[0].toString():
    x = 6;
    break;
case form[1].toString():
    x = 16; 
    break;
case form[2].toString():
    x = 23;
    break;
//So on and so forth
}

Is there any way to do either?

The Import.shuffle method takes a text file with 95 lines (each line being one character) and strings it together and Format.shuffle puts each of the original lines into individual array variables.

I can't convert this into an if else if chain because it's a 95 case switch (edit)

James Dunn
  • 8,064
  • 13
  • 53
  • 87
Kai Arakawa
  • 193
  • 1
  • 1
  • 14

4 Answers4

6

You could find the index of str within form, then switch based on the index. For example:

String shuff = Import.shuffle();
String[] form = new String[95];
for(int i = 0; i < 95; i++)
{
    form[i] = Format.shuffle(shuff, i);
}
int index=Arrays.asList(form).indexOf(str);
switch(index)
{
case 0:
    x = 6;
    break;
case 1:
    x = 16; 
    break;
case 2:
    x = 23;
    break;
//So on and so forth
}

However, neither of your proposed solutions will work because, when the code is compiled, the compiler needs to know exactly what each case value is instead of just knowing that it is in a variable. I'm not sure the exact reasons, but it may be for optimization or for making sure cases are not duplicated (which will compile incorrectly, IIRC). The bottom line is that form[0] is not a constant and the compiler wants a constant.

James Westman
  • 2,680
  • 1
  • 15
  • 20
5

You can't. Java's switch statement requires that case labels be constant expressions. If your code does not work with that restriction, you'll need to use if...elseif...else constructions instead.

See §14.11 of the JLS:

SwitchLabel:
   caseConstantExpression:
   caseEnumConstantName:
   default :

Alexis King
  • 43,109
  • 15
  • 131
  • 205
3

As mentioned before, Java requires constant expressions in cases on its switch statements.

You might need to design the structure better. I noticed that you are making a variable assignment on x, on each case. If this is your real code, you could possible map x possible values in a Map, or you could even maped them based on the index, in an int array in order to be possible to retrieve it even faster (with O(1) complexity).

Examples:

//With maps - based on string values
Map<String, Integer> values = new HashMap<String, Integer>();
values.put(form[0], 6);
values.put(form[1], 16);
values.put(form[2], 23);
//....
x = (int) values.GetValue(str); //str value is your indexer here.


//With arrays, based on indexes
int[] values = new int[] {6, 16, 23/*,...*/};
x = values[i]; // i is your indexer here.
Nick Louloudakis
  • 5,856
  • 4
  • 41
  • 54
0

If you really need to do this you will have to use a cascade of if/else. It would be no less efficient than what you imagine the switch statement to be. So:

if      (str.equals(form[0])) { x = 6; }
else if (str.equals(form[1])) { x = 16; }
else if (str.equals(form[2])) { x = 23; }

Takes many less lines of source as well.

AlanObject
  • 9,613
  • 19
  • 86
  • 142
  • You're taking a bit of a shortcut here. You're placing the `if` statements on one line as opposed to spreading them out. Also, for enough statements in a `switch` statement, [it can turn out to be more efficient.](http://stackoverflow.com/a/2158792/1079354) – Makoto Dec 21 '14 at 00:24
  • The reason it is more efficient is why the case conditions must be constant... to create a jump table. If you use the java 7/8 string variant it compiles like a cascaded if/else . – psaxton Dec 21 '14 at 04:52