Using switch statement with a range of value in each case?

208,862

Solution 1

Java has nothing of that sort. Why not just do the following?

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

if (isBetween(num, 1, 5)) {
  System.out.println("testing case 1 to 5");
} else if (isBetween(num, 6, 10)) {
  System.out.println("testing case 6 to 10");
}

Solution 2

The closest you can get to that kind of behavior with switch statements is

switch (num) {
case 1:
case 2:
case 3:
case 4:
case 5:
     System.out.println("1 through 5");
     break;
case 6:
case 7:
case 8:
case 9:
case 10:
     System.out.println("6 through 10");
     break;
}

Use if statements.

Solution 3

other alternative is using math operation by dividing it, for example:

switch ((int) num/10) {
    case 1:
        System.out.println("10-19");
        break;
    case 2:
        System.out.println("20-29");
        break;
    case 3:
        System.out.println("30-39");
        break;
    case 4:
        System.out.println("40-49");
        break;
    default:
        break;
}

But, as you can see this can only be used when the range is fixed in each case.

Solution 4

I don't think you can do that in Java. Best bet is to just put the code in the last case of the range.

switch (num) {
  case 1: case 2: case 3: case 4: case 5: 
     System.Out.Println("testing case 1 to 5");
     break;
  case 6: case 7: case 8: case 9: case 10:
     System.Out.Println("testing case 6 to 10");
     break;
  default:
     //
}

Solution 5

I know this post is old but I believe this answer deserves some recognition. There is no need to avoid the switch statement. This can be done in java but through the switch statement, not the cases. It involves using ternary operators.

public class Solution {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());

        switch ((1 <= num && num <= 5 ) ? 0 :
                (6 <= num && num <= 10) ? 1 : 2) {

            case 0:
                System.out.println("I'm between one and five inclusive.");
                break;
            case 1:
                System.out.println("I'm between 6 and 10 inclusive.");
                break;
            case 2:
                System.out.println("I'm not between one and five or 6 and 10 inclusive.");
                break;
        }
    }
}
Share:
208,862

Related videos on Youtube

davidx1
Author by

davidx1

Updated on July 08, 2022

Comments

  • davidx1
    davidx1 almost 2 years

    In Java, is it possible to write a switch statement where each case contains more than one value? For example (though clearly the following code won't work):

    switch (num) {
        case 1 .. 5:
            System.out.println("testing case 1 to 5");
            break;
        case 6 .. 10:
            System.out.println("testing case 6 to 10");
            break;
    }
    

    I think this can be done in Objective C, are there a similar thing in Java? Or should I just use if, else if statements instead?

    • arshajii
      arshajii over 10 years
      There even extensions in plain C that allow for this.
    • Eric
      Eric over 3 years
      In that case, maybe if/else is a better solution.
    • Luke Usherwood
      Luke Usherwood over 3 years
      Not today, but the Java folks are exploring options for this alongside Pattern Matching in switch expressions (borrowing heavily from Scala, I would say). Search "guard" in this document which captures possible ideas: cr.openjdk.java.net/~briangoetz/amber/switch-rehab.html
  • a54studio
    a54studio almost 11 years
    This works great and is simple. Also if you want to select numbers not in the range all you need is if(!isBetween... , good job.
  • Alexander Malakhov
    Alexander Malakhov almost 10 years
    @missingfaktor I've criticized your answer a bit. So, you would probably want to reply something. +1 though.
  • missingfaktor
    missingfaktor almost 10 years
    Sorry for the late response, I am not able to keep up with SO responses lately. I'll reply to your critique one by one. 1. Code is a bit more verbose, yes, and it also does some redundant computation. But that IMO is aiding clarity in this case. In your code, one has to remember the previous cases as one falls through the ladder.
  • missingfaktor
    missingfaktor almost 10 years
    As for requiring overloads and casts, that's not a valid criticism IMO. That Java has no sensible way of abstracting over numeric types says about Java's limitations, more than about this approach. You may want to explore Haskell's Num type-class if you wish to understand this point better.
  • Alexander Malakhov
    Alexander Malakhov almost 10 years
    @missingfaktor 1. I guess that's a matter of taste. When dealing with continuous intervals I personally like to think of ifs as if I'm gradually spilling off lower subrange. Further, a redundant computation isn't a problem at all, but redundant comparison is a bit worrying: it gets simpler to make adjacent comparisons out of sync, e.g. after some edit: if (isBetween(x, 1, 4)) {...} else if (isBetween(x, 6, 10)). Anyway, not a big deal.
  • Alexander Malakhov
    Alexander Malakhov almost 10 years
    2. Agreed - Java's limitation, but that's what we have to work with and your original code will be duplicated for various types. In this particular case a problem can be mitigated by using Number class, though Haskell's approach is better (never came to really learn Haskell, but it resembles "Concepts Light" of C++. Also, I believe you meant Real, not Num).
  • user1140237
    user1140237 over 8 years
    can you please give explanation too .. ?
  • zl9394
    zl9394 over 8 years
    The function range return some value according to the input argument, so the "range of value" detection could be done here, coupled with switch case clause.
  • Kamin Pallaghy
    Kamin Pallaghy about 8 years
    Can you explain this?? -- i do get the 'mini ifs' but other than that idk.
  • Williem
    Williem about 8 years
    @Tunaki this is a if..elseif alternative using in cascade the ternary operator(condition ? statementIfTrue : statementIfFalse).
  • Sameer Kazi
    Sameer Kazi almost 8 years
    This is worked for my use case, I have 2 int variable and I want to check is that 2 variable are in same range like (10-20),(20-30),.... like this
  • Ch Vas
    Ch Vas over 7 years
    Excellent solution! don't forget to check for null using if (messages.floorEntry(value)!=null) if you use an Integer value
  • brady
    brady over 7 years
    @ChVas The way the map is set up here, floorEntry() will never return null (inserting the Integer.MIN_VALUE key is intended to prevent that). But, regardless of your value type, you need to decide how to handle keys outside the valid range.
  • missingfaktor
    missingfaktor over 6 years
    @MCEmperor, please don't edit my answer with your personal formatting preferences. That's not a useful edit.
  • MC Emperor
    MC Emperor over 6 years
    @missingfaktor Sorry. But that edit was approved a long time ago; I didn't even remember I had ever done that.
  • Stefan
    Stefan about 6 years
    This works nicely with http status codes divided by 100.
  • Perdi Estaquel
    Perdi Estaquel about 5 years
    This is what I always do, but also add a comment in between cases, eg.: // 10 - 15 see below default
  • Daniel Widdis
    Daniel Widdis almost 4 years
    Nice solution! With Java 7 and higher you could also switch on a String so your cases are even more self-documenting, e.g., switch ((1 <= num && num <= 5 ) ? "1 .. 5" : ... and then case "1 .. 5":.
  • nmatt
    nmatt over 3 years
    @DanielWiddis: I would suggest using an enum instead of strings, to ensure consistency.
  • nmatt
    nmatt over 3 years
    I would suggest using an enum instead of magic int values.
  • Daniel Widdis
    Daniel Widdis over 3 years
    @nmatt Generally agree. I was trying to permit the use of the "1 .. 5" style syntax.
  • nmatt
    nmatt over 3 years
    @DanielWiddis: Certainly a good thing; I would name the enum constants something like FROM_1_TO_5. Usually the ranges have a certain meaning, and in that case the enum constants can be named according to the meaning of the range.
  • Daniel Widdis
    Daniel Widdis over 3 years
    I think we can agree either option is better than 0, 1, or 2.
  • Hasen
    Hasen over 3 years
    Weird that switch statements seem almost useless in most languages I've come across, not sure why they don't develop them a bit more. Even something simple like a range is strangely not possible.
  • Hasen
    Hasen over 3 years
    I'm almost certain that's exactly what he's trying to avoid.
  • Jeffrey
    Jeffrey over 3 years
    @Hasen which is why I recommend using if statements instead :)
  • Hasen
    Hasen over 3 years
    Well then a comment would've been better like Eric Wang above.
  • Don Hosek
    Don Hosek about 3 years
    Although in a critical loop, I would expect this to be non-performant. Each ternary operator compiles to an if-branch statement and then there's another in the actual switch, so you end up having double the number of if-branches taking place in the compiled byte code. The string solution also relies on expensive string comparisons. enum comparisons, at least are cheaper.