The switch statement

Figure 152. Better: Using switch Slide presentation
...
switch(number) {
    case 1: System.out.println("Monday"); break;
    case 2: System.out.println("Tuesday"); break;
    case 3: System.out.println("Wednesday"); break;
    case 4: System.out.println("Thursday"); break;
    case 5: System.out.println("Friday"); break;
    case 6: System.out.println("Saturday"); break;
    case 7: System.out.println("Sunday"); break;

    default: System.out.println("Invalid number " + number); break;
} ...
Enter a weekday number (1=Monday, 2=Tuesday,...) : 6
Saturday

Figure 153. switch Syntax Slide presentation
switch(expression) {
[case value_1 :
    [statement]*
    [break;] ]
[case value_2 :
    [statement]*
    [break;] ]
  ...
[case value_n :
    [statement]*
    [break;] ]
[default:
    [statement]*
    [break;] ]
}

exercise No. 63

Why break?

Q:

Do we need break statements in Figure 152, “Better: Using switch? Rewrite Figure 151, “Numbers to day's names: The hard way ” replacing all conditions by switch / case statements without using break. What do you observe on execution?

A:

Figure 151, “Numbers to day's names: The hard way ” can be rewritten as:

try (final Scanner scan = new Scanner(System.in)) {
  System.out.print("Enter a weekday number (1=Monday, 2=Tuesday,...) : ");
  final int number = scan.nextInt();
  switch(number) {
    case 1: System.out.println("Monday");
    case 2: System.out.println("Tuesday");
    case 3: System.out.println("Wednesday");
    case 4: System.out.println("Thursday");
    case 5: System.out.println("Friday");
    case 6: System.out.println("Saturday");
    case 7: System.out.println("Sunday");

    default: System.out.println("Invalid number " + number);
  }
}

Entering a day's number 5 yields:

Enter a weekday number (1=Monday, 2=Tuesday,...) : 5
Friday
Saturday
Sunday
Invalid number 5

So the break statements effectively prohibit fall-through towards subsequent case labels. Moving 7 / Sunday to the beginning this becomes even clearer:

...
switch(number) {
   case 7: System.out.println("Sunday"); // Deliberately moved to the top
   case 1: System.out.println("Monday");
   case 2: System.out.println("Tuesday");
   case 3: System.out.println("Wednesday");
   case 4: System.out.println("Thursday");
   case 5: System.out.println("Friday");
   case 6: System.out.println("Saturday");
   default: System.out.println("Invalid number " + number);
} ...

This time entering a value of 5 again we no longer see "Sunday" on output:

Enter a weekday number (1=Monday, 2=Tuesday,...) : 5
Friday
Saturday
Invalid number 5

Thus fall-through does not depend on numerical case label ordering but solely on their order of appearance within code.

exercise No. 64

Extending to month days

Q:

Consider January 2052:

Monday Tuesday Wednesday Thursday Friday Saturday Sunday
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

Write an application converting a given day's number within January 2052 (this may be generalized to arbitrary months) to its name e.g.:

Enter a day's number:>23
Tuesday

Tip

The modulo operator % is your friend.

A:

With respect to Figure 152, “Better: Using switch two modification are being required:

...
switch(day % 7) {
   case 1: System.out.println("Monday"); break;
   case 2: System.out.println("Tuesday"); break;
   ...
   case 0: System.out.println("Sunday"); break;
}
Figure 154. Switching on strings Slide presentation
String month, season;  
...
// Since Java 7: String based case labels
switch(month) {
    case "March": case "April": case "May":
       season = "Spring"; break;

    case "June": case "July": case "August":
        season = "Summer"; break;

    case "September": case "October": case "November":
       season = "Autumn"; break;

    case "December": case "January": case "February":
       season = "Winter"; break;
    }
}

exercise No. 65

Converting day's names to numbers.

Q:

Consider the reverse problem to Figure 150, “Converting numbers to day's names ”: We want to map a given day's name to its number as in the following example:

Enter a weekday (Monday to Sunday): Friday
5

Issue an error message in case an inappropriate text is being entered:

Enter a weekday (Monday to Sunday): July
Unknown day name 'July'

Tip

  1. Starting from Java 7 String based switch statements are allowed.

  2. You may read strings into your application using Scanner.next().

A:

try (final Scanner scan = new Scanner(System.in)) {
    System.out.print("Enter a weekday (Monday to Sunday):>");
    final String day = scan.next();
    switch(day) {
        case "Monday": System.out.println(1); break;
        case "Tuesday": System.out.println(2); break;
        case "Wednesday": System.out.println(3); break;
        case "Thursday": System.out.println(4); break;
        case "Friday": System.out.println(5); break;
        case "Saturday": System.out.println(6); break;
        case "Sunday": System.out.println(7); break;
        default: System.out.println("Unknown day name '" + day + "'");
                 break;
    }
}

exercise No. 66

Day categories.

Q:

We want to group working days into categories:

Day Category
Monday Start of work week
Tuesday Midweek
Wednesday
Thursday
Friday End of work week
Saturday Weekend
Sunday

Example execution:

Enter a weekday (Monday to Sunday):>Wednesday
Midweek

Tip

Sometimes omitting break statements allowing for fall-through is your friend.

A:

try (final Scanner scan = new Scanner(System.in)) {
    System.out.print("Enter a weekday (Monday to Sunday):>");
    final String day = scan.next();
    switch(day) {
        case "Monday": System.out.println("Start of work week"); break;

        case "Tuesday":
        case "Wednesday":
        case "Thursday": System.out.println("Midweek"); break;

        case "Friday": System.out.println("End of work week"); break;

        case "Saturday":
        case "Sunday": System.out.println("Weekend"); break;

        default: System.out.println("Unknown day name " + day); break;
    }
}

exercise No. 67

Roman numerals, using switch

Q:

Re-implement Roman numerals using a switch statement rather then an if ... else if ... else.

A:

try (final Scanner scan = new Scanner(System.in)) {

  System.out.print("Enter a number:>");
   final int number = scan.nextInt();

   switch (number) {
      case 1: System.out.println("I"); break;
      case 2: System.out.println("II"); break;
      case 3: System.out.println("III"); break;
      case 4: System.out.println("IV"); break;
      case 5: System.out.println("V"); break;
      case 6: System.out.println("VI"); break;
      case 7: System.out.println("VII"); break;
      case 8: System.out.println("VIII"); break;
      case 9: System.out.println("IX"); break;
      case 10: System.out.println("X"); break;

      default:System.out.println("Decimal value " + number + " not yet implemented");
              break;
   }
}