4

I'm trying to simplify a Card class, and am wondering if there's any way to use a range of values in a switch statement?

CONSIDER:

 if((card<14))
     suit="Hearts";
     else
     if((card>14)&&(card<27))
         suit="Clubs";

             etc.

Instead I'd like to use a switch statement, such as:

switch(card){
    case1: through case13:
    suit="Hearts";
    break;

       etc.

I wasn't able to find anything in the Java Tutorials that suggest there is such a variation of switch. But is there?

Kailua Bum
  • 1,368
  • 7
  • 25
  • 40
dwwilson66
  • 6,806
  • 27
  • 72
  • 117
  • 4
    For this particular case, you could do a `switch` on `(card-1) / 13`, or something like that. – Louis Wasserman Mar 22 '12 at 19:51
  • @LouisWasserman: If I read this right, `int foo = (card-1) / 13;` will yield integer values 1-4, which can then be passed to the `switch`. Am I understanding that properly? – dwwilson66 Mar 23 '12 at 19:42
  • Yes. Or something like that, depending on how you've numbered the cards. – Louis Wasserman Mar 23 '12 at 20:12
  • possible duplicate of [In Java,Using switch statement with a range of value in each case?](http://stackoverflow.com/questions/10873590/in-java-using-switch-statement-with-a-range-of-value-in-each-case) – GabrielOshiro May 20 '15 at 20:29

5 Answers5

8

About the best you can do is something like this (see below). So in some cases (no pun intended :)), it's just better to use an if statement.

switch(card){
    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:
        suit="Hearts";
        break;
}

However, another approach you could consider is using a map.

Map<Integer, String> map = new HashMap<Integer, String>();
for (int i = 1; i <= 14; ++i) {
  map.put(i, "Hearts");
}
for (int i = 15; i <= 26; ++i) {
  map.put(i, "Clubs");
}

Then you can look up the card's suit using the map.

String suit1 = map.get(12); // suit1 will be Hearts after the assignment
String suit2 = map.get(23); // suit2 will be Clubs after the assignment
dcp
  • 54,410
  • 22
  • 144
  • 164
  • 2
    Map...another interesting feature beyond my newbie-ness...I've got a weekend reseach project or two. :) Thanks. – dwwilson66 Mar 23 '12 at 19:36
3

Java doesn't allow you to do any such thing unfortunately. Other JVM languages might though, i.e., Scala.

Johan Sjöberg
  • 47,929
  • 21
  • 130
  • 148
1

This was proposed in Project Coin some time back.

Basically the switch operator now operates on built-ins and Objects. While a well defined range exists for selecting two built-ins, switches that are operating on Objects don't have a well defined range. Currently two classes of objects are supported, Strings and Enum.

Is "car" between "A" and "D"? Depends on how you like to handle case sensitivity.

Is MyEnum.ONE before MyEnum.TWO? Depending on it in production code is a very bad idea (as Josh Bloch would love to explain), and if you need an ordering, the maintainable way is to implement a non-index bound comparator. This much better practice would be hard to integrate into a simple switch without forcing every enum to implement an ordering (which doesn't make sense for enums that are not ordered).

The project coin proposal is found here.

Josh Bloch's excellent presentation on why not to rely on implicit enum ordering is found within the presentation here.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
0

This is about the best you're going to get:

switch(card){
    case1:
    case2:
    case3:
        suit="Hearts";
        break;
bvulaj
  • 5,023
  • 5
  • 31
  • 45
0

Some libraries provide the "Range" feature. It will not work with the switch syntax but it should do the job.

For example, the Range class of Guava.

Range hearts = Ranges.closed(1, 13);
Range clubs = Ranges.closed(14, 17);
// ...

if (hearts.contains(value)) {
    // case heart...
} else if (clubs.contains(value) {
    // case club...
} // ...
Benoit Courtine
  • 7,014
  • 31
  • 42