use relational operators in switch

前端 未结 7 2068
终归单人心
终归单人心 2020-12-11 06:55

Is there a way to use relational operators (<,<=,>,>=) in a switch statement?

int score = 95;

switch(score)  {
   case (score >= 90):
      // do s         


        
相关标签:
7条回答
  • 2020-12-11 07:34

    It will never work. You should understand what switch does in the first place.

    It will execute the statements falling under the case which matches the switch argument.

    In this case, score is an argument which is 95 but score>=90 will always evaluate to either true or false and never matches an integer.

    You should use if statements instead.

    Also Java doesn't allow booleans in switch cases so yea.

    0 讨论(0)
  • 2020-12-11 07:36

    This might help you if you need to do it with switch itself,

    char g ='X';
                int marks = 65;
                switch(marks/10)
                {
                    case 1:
                    case 2:
                    case 3:
                    case 4: g = 'F';
                            break;
                    case 5: g = 'E';
                            break;
                    case 6: g = 'D';
                            break;
                    case 7: g = 'C';
                            break;
                    case 8: g = 'B';
                            break;
                    case 9: 
                    case 10: g = 'A';       
                             break;
                }
                System.out.println(g);
    

    It works this way,

        if(marks<50)
                    g='F';
                else if(marks<60)
                    g='E';
                else if(marks<70)
                    g='D';
                else if(marks<80)
                    g='C';
                else if(marks<90)
                    g='B';
                else if(marks<=100)
                    g='A';
    
    0 讨论(0)
  • 2020-12-11 07:36

    Obviously, this is not possible as a language construct. But, just for fun, we could implement it by ourselves!

    public class Switch<T, V> {
    
        public static interface Action<V> {
            V run();
        }
    
        private final T value;
        private boolean runAction = false;
        private boolean completed = false;
        private Action<V> actionToRun;
    
        public Switch(T value) {
            this.value = value;
        }
    
        static public <T, V> Switch<T, V> on(T value) {
            return new Switch<T, V>(value);
        }
    
        public Switch<T, V> ifTrue(boolean condition) {
            runAction |= condition;
            return this;
        }
    
        public Switch<T, V> ifEquals(T other) {
            return ifTrue(value.equals(other));
        }
    
        public Switch<T, V> byDefault(Action<V> action) {
            this.actionToRun = action;
            return this;
        }
    
        public Switch<T, V> then(Action<V> action) {
            if (runAction && !completed) {
                actionToRun = action;
                completed = true;
            }
            return this;
        }
    
        public V getResult() {
            if (actionToRun == null) {
                throw new IllegalStateException("none of conditions matched and no default action was provided");
            }
            return actionToRun.run();
        }
    }
    

    Switch accepts any value to switch on and then provides functionality to match over boolean conditions (ifTrue method) or by exact matches (ifEquals method). Providing a value to switch on is needed just for the latter feature.

    After building the conditions, user invokes getResult to obtain the result.

    For example, we could create a method that tells us what it thinks about our score:

    String tellMeMyScore(int score) {
        return Switch.<Integer, String> on(score).byDefault(new Action<String>() {
            public String run() {
                return "really poor score";
            }
        }).ifTrue(score > 95).then(new Action<String>() {
            public String run() {
                return "you rock!";
            }
        }).ifTrue(score > 65).then(new Action<String>() {
            public String run() {
                return "not bad, not bad";
            }
        }).ifEquals(42).then(new Action<String>() {
            public String run() {
                return "that's the answer!";
            }
        }).getResult();
    }
    

    This simple test:

    for (int score : new int[] { 97, 85, 66, 55, 42, 32, 4 }) {
        System.out.println(score + ": " + tellMeMyScore(score));
    }
    

    Prints out:

    97: you rock!
    85: not bad, not bad
    66: not bad, not bad
    55: really poor score
    42: that's the answer!
    32: really poor score
    4: really poor score
    
    0 讨论(0)
  • 2020-12-11 07:38

    No you can not.
    From jls-14.11

    The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, String, or an enum type (§8.9), or a compile-time error occurs.  
    

    Relational operators (<,<=,>,>=) results in boolean and which is not allowded.

    All of the following must be true, or a compile-time error occurs:

    • Every case constant expression associated with a switch statement must be assignable (§5.2) to the type of the switch Expression.

    • No two of the case constant expressions associated with a switch statement may have the same value.

    • No switch label is null.

    • At most one default label may be associated with the same switch statement.

    0 讨论(0)
  • 2020-12-11 07:40

    Unfortunately NO, though you can use case fall (kind of hacky) by grouping multiple case statements without break and implement code when a range ends:

    int score = 95;
    switch(score) {
     ..
     case 79: System.out.println("value in 70-79 range"); break;
     case 80:
     ..
     case 85: System.out.println("value in 80-85 range"); break;
     case 90:
     case 91:
     case 92:
     case 93:
     case 94:
     case 95: System.out.println("value in 90-95 range"); break;
     default: break;
    }
    

    IMHO, using if would be more appropriate in your particular case.

    0 讨论(0)
  • 2020-12-11 07:40

    The docs for switch-case statement state:

    a switch statement tests expressions based only on a single integer, enumerated value, or String object.

    So there is no boolean. Doing so would make no sence since you only have two values: true or false.

    What you could do is write a method which checks the score and then returns a one of the types switch can handle

    For example:

    enum CheckScore {
        SCORE_HIGHER_EQUAL_90,
        ...
    }
    
    
    public CheckScore checkScore(int score) {
        if(score >= 90) {
            return SCORE_HIGHER_EQUAL_90;
        } else if(...) {
            return ...
        }
    }
    

    and then use it in your switch:

    switch(checkScore(score))  {
       case SCORE_HIGHER_EQUAL_90:
          // do stuff
    }
    

    ... Or You could just use if, else-if, else directly!

    0 讨论(0)
提交回复
热议问题