Java switch statement multiple cases

前端 未结 13 937
后悔当初
后悔当初 2020-11-27 14:43

Just trying to figure out how to use many multiple cases for a Java switch statement. Here\'s an example of what I\'m trying to do:

switch (variable)
{
    c         


        
相关标签:
13条回答
  • 2020-11-27 14:48

    // Noncompliant Code Example

    switch (i) {
      case 1:
        doFirstThing();
        doSomething();
        break;
      case 2:
        doSomethingDifferent();
        break;
      case 3:  // Noncompliant; duplicates case 1's implementation
        doFirstThing();
        doSomething();
        break;
      default:
        doTheRest();
    }
    
    if (a >= 0 && a < 10) {
      doFirstThing();
    
      doTheThing();
    }
    else if (a >= 10 && a < 20) {
      doTheOtherThing();
    }
    else if (a >= 20 && a < 50) {
      doFirstThing();
      doTheThing();  // Noncompliant; duplicates first condition
    }
    else {
      doTheRest();
    }
    

    //Compliant Solution

    switch (i) {
      case 1:
      case 3:
        doFirstThing();
        doSomething();
        break;
      case 2:
        doSomethingDifferent();
        break;
      default:
        doTheRest();
    }
    
    if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
      doFirstThing();
      doTheThing();
    }
    else if (a >= 10 && a < 20) {
      doTheOtherThing();
    }
    else {
      doTheRest();
    }
    
    0 讨论(0)
  • 2020-11-27 14:50

    It is possible to handle this using Vavr library

    import static io.vavr.API.*;
    import static io.vavr.Predicates.*;
    
    Match(variable).of(
        Case($(isIn(5, 6, ... , 100)), () -> doSomething()),
        Case($(), () -> handleCatchAllCase())
    );
    

    This is of course only slight improvement since all cases still need to be listed explicitly. But it is easy to define custom predicate:

    public static <T extends Comparable<T>> Predicate<T> isInRange(T lower, T upper) {
        return x -> x.compareTo(lower) >= 0 && x.compareTo(upper) <= 0;
    }
    
    Match(variable).of(
        Case($(isInRange(5, 100)), () -> doSomething()),
        Case($(), () -> handleCatchAllCase())
    );
    

    Match is an expression so here it returns something like Runnable instance instead of invoking methods directly. After match is performed Runnable can be executed.

    For further details please see official documentation.

    0 讨论(0)
  • 2020-11-27 14:51

    Maybe not as elegant as some previous answers, but if you want to achieve switch cases with few large ranges, just combine ranges to a single case beforehand:

    // make a switch variable so as not to change the original value
    int switchVariable = variable;
    
    //combine range 1-100 to one single case in switch
    if(1 <= variable && variable <=100)
        switchVariable = 1;
    switch (switchVariable) 
    { 
        case 0:
            break; 
        case 1:
            // range 1-100
            doSomething(); 
            break;
        case 101: 
            doSomethingElse(); 
            break;
        etc.
    } 
    
    0 讨论(0)
  • 2020-11-27 14:54

    According to this question, it's totally possible.

    Just put all cases that contain the same logic together, and don't put break behind them.

    switch (var) {
        case (value1):
        case (value2):
        case (value3):
            //the same logic that applies to value1, value2 and value3
            break;
        case (value4):
            //another logic
            break;
    }
    

    It's because case without break will jump to another case until break or return.

    EDIT:

    Replying the comment, if we really have 95 values with the same logic, but a way smaller number of cases with different logic, we can do:

    switch (var) {
         case (96):
         case (97):
         case (98):
         case (99):
         case (100):
             //your logic, opposite to what you put in default.
             break;
         default: 
             //your logic for 1 to 95. we enter default if nothing above is met. 
             break;
    }
    

    If you need finer control, if-else is the choice.

    0 讨论(0)
  • 2020-11-27 14:56

    for alternative you can use as below:

    if (variable >= 5 && variable <= 100) {
            doSomething();
    
        }
    

    or the following code also works

    switch (variable)
    {
        case 5:
        case 6:
        etc.
        case 100:
            doSomething();
        break;
    }
    
    0 讨论(0)
  • 2020-11-27 14:57

    One alternative instead of using hard-coded values could be using range mappings on the the switch statement instead:

    private static final int RANGE_5_100 = 1;
    private static final int RANGE_101_1000 = 2;
    private static final int RANGE_1001_10000 = 3;
    
    public boolean handleRanges(int n) {
        int rangeCode = getRangeCode(n);
        switch (rangeCode) {
            case RANGE_5_100: // doSomething();
            case RANGE_101_1000: // doSomething();
            case RANGE_1001_10000: // doSomething();
            default: // invalid range
        }
    }
    
    private int getRangeCode(int n) {
        if (n >= 5 && n <= 100) {
            return RANGE_5_100;
        } else if (n >= 101 && n <= 1000) {
            return RANGE_101_1000;
        } else if (n >= 1001 && n <= 10000) {
            return RANGE_1001_10000;
        }
    
        return -1;
    }
    
    0 讨论(0)
提交回复
热议问题