-1

My Java textbook asked me about the following error:

switch (score)
        {
            case (score > 90):
                grade = 'A';
                break;
            case (score > 80):
                grade = 'B';
                break;
            default:
                grade = 'C';
        }

I already know where the error is:

  • Switch statements aren't built for comparisons like (score > 90); that's for if/else statements.

But this got me wondering: How could a switch statement efficiently account for ranges of integers?

The most obvious example I could think of is below, but I find it rather brute-force:

switch (score)
    {
        case 90: case 91: case 92: case 94: case 95:
        case 96: case 97: case 98: case 99: case 100:
            grade = 'A';
            break;
        case 80: case 81: case 82: case 84: case 85:
        case 86: case 87: case 88: case 89:
            grade = 'B';
            break;
        default:
            grade = 'C';
    }

How else could a concept like this be expressed in a switch statement?

Mark Puchala II
  • 634
  • 2
  • 8
  • 25
  • 2
    Why aren't you allowed to use `if-else`? – Zereges Jul 07 '15 at 17:05
  • 2
    There's no other way of doing that with a switch statement. That's why you use an if statement :) – tnw Jul 07 '15 at 17:06
  • possible duplicate of [Java switch statement multiple cases](http://stackoverflow.com/questions/5086322/java-switch-statement-multiple-cases) – sstan Jul 07 '15 at 17:06
  • @Mark your question is unclear to me: from your code example it seems that you already know what a switch statement can and can't do. So in the case above you obviously *should not* use it because you're dealing with ranges. When you'll deal with exact values then it may be proper to use switch/case. – Nir Alfasi Jul 07 '15 at 17:07
  • The brute force method actually won't work! What happens if someone has a score that is 92.4? – SwiftySwift Jul 07 '15 at 17:08
  • @Marcin: Good point in general, but the OP did not imply that `score` is `float` or `double`. – Nayuki Jul 07 '15 at 17:10
  • Thank you for all your responses! Because we all agree if/else is simply the way to go, the point of my question was to understand what ways a switch statement could still replicate the same approach. While not only serving as great examples of *why* if/else is superior, the answers below are also exemplify creative approaches that will likely prove useful down the road. – Mark Puchala II Jul 07 '15 at 18:00
  • In general, when I see myself using a switch statement, my next thought is "how should I refactor this to not use a switch". Often with a switch some refactor is a better solution. That being said, it does not address your specific question. – Mark Schultheiss Jul 07 '15 at 19:07
  • Not a duplicate post. The point of this question was to find how one could still utilize a switch statement for this purpose regardless of the efficiency of if/else statements. – Mark Puchala II Jul 09 '15 at 20:26

7 Answers7

8

If you take advantage of the fact that grades change with every change of 10 in the score, and assuming that score is an integer data type, then you can divide by 10 to eliminate most cases:

switch (score / 10)
{
    case 9:
    case 10:
        grade = 'A';
        break;
    case 8:
        grade = 'B';
        break;
    default:
        grade = 'C';
}

If there is no such rule (if the "grade" bucket sizes are differing and arbitrary), then the best you can do is if/else-if/else statements.

rgettman
  • 176,041
  • 30
  • 275
  • 357
1

The short answer: it can't. The long answer: The switch statement cannot accept expressions like this since switch statements operate on single values of a variable rather than a range of variables like you've shown.

Bizkit
  • 384
  • 1
  • 10
1

May be not a best answer but very simple approach can be

int temp;

if(score > 90) 
 temp = 1;
else if(score > 80) 
 temp = 2;


switch (temp)
        {
            case (1):
                grade = 'A';
                break;
            case (2):
                grade = 'B';
                break;
            default:
                grade = 'C';
        }
Rishi Saraf
  • 1,644
  • 2
  • 14
  • 27
1

This version I just made could be deemed more elegant:

 int score_new = score/10 

\\This gets you the first digit.. make sure score_new is int and not double

switch (score_new)

{
   case 10: case 9:
        grade = 'A';
        break;        
    case 8:
        grade = 'B';
        break;
    default:
        grade = 'C';
}
Billy Norbu
  • 168
  • 9
1

In some programming languages something like this

switch (true) {
  case (0 <= val &&  val < 1000): /* do something */ break;
  case (1000 <= val &&  val < 2000): /* do something */ break;
  ...
  case (29000 <= val &&  val < 30000): /* do something */ break;
}

is possible but first it's not very performant and second java doesn't accept that. So use if-then-else:

 int val = 500;
 if (0 <= val &&  val < 1000){ System.out.println("Test");}
 else if (1000 <= val &&  val < 2000){ /* do something */}
 else if (29000 <= val &&  val < 30000){ /* do something */}
beresfordt
  • 5,088
  • 10
  • 35
  • 43
aljoshare
  • 792
  • 9
  • 16
0

For your case, if statement is better and readable. switch statement is good for small set of int or enum values.

spgodara
  • 984
  • 9
  • 10
-1

In Java, a switch statement can only test int values (since Java 1.0), enum values (since Java 5.0), and String values (since Java 7.0), and only be able to test for equality. Note that byte, short, and char can be upcasted to int. But long, float, and double values cannot be tested.

Legal examples:

int x = (...);
switch (x) {
    case 0: (...)
}

byte x = (...);
switch (x) {
    case 0: (...)
}

String x = (...);
switch (x) {
   case "a": (...)
}

Illegal examples:

long x = (...);
switch (x) {
    case 0: (...)
}

double x = (...);
switch (x) {
    case 0.0: (...)
}
Nayuki
  • 17,911
  • 6
  • 53
  • 80