Brian Nyagol
Brian Nyagol

Reputation: 69

Using a method in the case section of a switch statement

I am trying to use a switch statement in my grading system and I have not found a proper way to include a range of values in the switch case section. I however researched here and found the use of isBetween:

public static isBetween(int x, int lower, int upper)
{
    return lower <=x && x<=upper;
}

I tried to use this in this manner to check if the mark submitted was between a range of 1-20:

switch (mark) {
    case isBetween(0, 20):
        System.out.println("Grade is E");
        break;
    case isBetween(21, 29):
        System.out.println("Grade is D");
        break;
}

I know this is wrong since it does not work. Will somebody help correct my code? In this case I have to use a switch statement.

Upvotes: 2

Views: 3982

Answers (3)

Leo
Leo

Reputation: 6570

what if

public static void main(String[] args) {
    Grade g = Grade.gradeValueOf(20);
    switch(g){
    case D:
        //do something for D
        break;
    case E:
        //do something for E
        break;
    }
}

and

public enum Grade {
E(0,20),D(21,29);
private int min,max;

private Grade(int min, int max) {
    this.min = min;
    this.max = max;
}

public static Grade gradeValueOf(int val){
    for(Grade g:Grade.values()){
        if (g.min <= val && val <= g.max){
            return g;
        }
    }
    return null;
}
}

you're still using a switch :-)

Upvotes: 1

Loktopus
Loktopus

Reputation: 462

In a switch statement, each case evaluates whether or not the input parameter in switch(param) is equal to that case. For example, if I were to write switch(3), only case 3: would execute.

There are a couple problems here. First, the method in your case is returning a boolean, but you are doing a switch on an int. So when the code checks to see if the input parameter mark is equal to isBetween(0,20), it is trying to compare an int and a boolean. You don't actually want to do this. You want to see if mark is one of the values 0, 1, 2, 3, 4, 5.. 20. If you were to use a case statement here, you would need to compare mark to a case for each of those values.

Second, as Eric states, you need to use static values in your case statements. That means you can't have a function return a String, because it might change based on the internals of the function.

Also, isBetween() requires you to input the number you want to determine is inbetween two others. Right now your code doesn't have the right number of inputs. The method should also declare that it is returning a boolean, as Tiny pointed out. You always need a return type when defining a method.

The best way to do this probably doesn't use switch-case, and would look something like this:

public static boolean isBetween(int x, int lower, int upper)
{
    return lower <=x && x<=upper;
}

public void printMark(int mark){
    if(isBetween(mark, 0, 20))
        System.out.println("Grade is E");
    else if(isBetween(mark, 21, 29))
        System.out.println("Grade is D");
}

Since you have to use switch-case, I would tweak it so it's like this:

private static final int GRADE_E = 0;
private static final int GRADE_D = 1;

public static boolean isBetween(int x, int lower, int upper)
{
    return lower <=x && x<=upper;
}

private int getMarkCode(int markParam){
    if(isBetween(markParam, 0, 20))
        return GRADE_E;
    else if(isBetween(markParam, 21, 29))
        return GRADE_D;
}

public void printMark(int mark){
    switch(getMarkCode(mark)){
        case GRADE_E:
            System.out.println("Grade is E");
            break;
        case GRADE_D:
            System.out.println("Grade is D");
            break;
     }
}

Notice how this is longer than the first case and fairly redundant. Also notice how I named the codes I used in the case statement. A lot of case statements you see that are well written won't use numbers, but will instead use descriptive names. Especially when you use codes without any inherent meaning, like I did here with 0 representing a grade of E and a 1 representing a grade of D, you want a descriptive name. Generally, however, you should avoid using codes, and instead use the value the code is trying to represent, whether that value be a string, int, or some type of object.

Upvotes: 3

keshlam
keshlam

Reputation: 8058

If you "have to" use a switch/case statement, try:

char grade='?';
switch (mark) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
    case 18:
    case 19:
    case 20:
        grade='F'; // I've never seen anyone given a grade of 'E'...
        break;
    case 21:
    case 22:
    case 23:
    case 24:
    case 25:
    case 26:
    case 27:
    case 28:
    case 29:
        grade='D';
        break;
}
System.out.println("Grade is "+grade);

You can't use expressions as case values unless they can be fully resolved at compile time. The reason has to do with how switch/case is generally compiled, which is to turn it into a jump table with the value being switched on used to index into that table.

Upvotes: 1

Related Questions