# Motivating examples for switch/case in Java

Students first see switch/case as a second syntax for if/else, but eventually they should see its strength in creating cascades. I know of the traditional example of printing a cumulative song, like "Twelve Days of Christmas", and below I've placed some code I use to illustrate the difference in use-case between if statements and switch cases. It nicely prints out all 108 lines of the song Alouette in 44 lines of code.

The only other motivating example I can think of is a graduated tax calculator (based on the US Federal Income Tax), where cascades can be a nice way to approach the problem.

These examples are fine, but it's not enough to get the lightbulb to flick on for most of my students. What I need is a few more motivating examples that really show students why switch/case is useful. What other examples show this clearly?

    System.out.println("Alouette, gentille alouette,\n"
+ "Alouette, je te plumerai.\n");

for(int verse = 1; verse <= 8; verse++){
if(verse == 1){
System.out.println("Je te plumerai la tête.\nJe te plumerai la tête.");
} else if (verse == 2){
System.out.println("Je te plumerai le bec.\nJe te plumerai le bec.");
} else if (verse == 3){
System.out.println("Je te plumerai les yeux.\nJe te plumerai les yeux.");
} else if (verse == 4){
System.out.println("Je te plumerai le cou.\nJe te plumerai le cou.");
} else if (verse == 5){
System.out.println("Je te plumerai les ailes.\nJe te plumerai les ailes.");
} else if (verse == 6){
System.out.println("Je te plumerai les pattes.\nJe te plumerai les pattes.");
} else if (verse == 7){
System.out.println("Je te plumerai la queue.\nJe te plumerai la queue.");
} else if (verse == 8){
System.out.println("Je te plumerai le dos.\nJe te plumerai le dos.");
}

switch(verse){
case 8:
System.out.println("Et le dos! Et le dos!");
case 7:
System.out.println("Et la queue! Et la queue!");
case 6:
System.out.println("Et les pattes! Et les pattes!");
case 5:
System.out.println("Et les ailes! Et les ailes!");
case 4:
System.out.println("Et le cou! Et le cou!");
case 3:
System.out.println("Et les yeux! Et les yeux!");
case 2:
System.out.println("Et le bec! Et le bec!");
case 1:
System.out.println("Et la tête! Et la tête!");
default:
System.out.println("Alouette! Alouette!\n"
+ "Ah-ah-ah-ah\n");
}

System.out.println("Alouette, gentille alouette,\n"
+ "Alouette, je te plumerai.\n");

• urrm. why don't you have break; in each case? I thought it was necessary... – ItamarG3 Jun 12 '17 at 15:04
• The choice about where (and if) to use breaks is the great strength of the structure. If you put a break in every case, you will be back to an if/else structure. But if you skip some... try running the code =D – Ben I. Jun 12 '17 at 15:06
• It will create chains, won't it? – ItamarG3 Jun 12 '17 at 15:09
• I could tell you, but that would spoil the surprise. (SPOILER ALERT: yes, it does.) – Ben I. Jun 12 '17 at 15:14
• If the students have been introduced to the "clean code" concept, the switch/case construct is easier to read even if there's a break for each case. Makes it obvious that it is a multi-branch decision point. – Gypsy Spellweaver Jun 12 '17 at 15:23

Consider why you might prefer to use a switch in a production environment:

1. Fall through processing. The blackjack example given by @Peter is a good example of this because it mirrors how we think about the problem: all of the face cards fall into the same case & the code follows suit. Be careful with this though, it's easy to abuse this to get terser code at the expense of readability
2. Default handlers. Personally, I find this most useful not in a 'single moment of code', but over a series of refinements. For instance, it's common to not have all your logic to handle multiple situations in place when you start coding, but it's also easy to miss a special case that you meant to add later. A default handler is a convenient & concise way to stub out code that you haven't yet gotten to. Default handlers for that throw an exceptions or log the event can help avoid silent failures & are less likely to get 'coded out' by an mistakenly adding or removing an if or else.
3. Maintainability. I find it safer to add & remove code from a switch statement than an if / else if / else block as I'm more likely to accidentally omit an else from an else if than I am to omit a break from a switch.
4. As per Joshua Bloch's Effective Java: "Switches on enums are good for augmenting external enums types with constant-specific behavior." For example if you cannot change the source for an Operation enum, but need add support for an inverse method:

public static Operation inverse(Operation op){
switch(op){
case PLUS:   return Operation.MINUS;
case MINUS:  return Operation.PLUS;
case TIMES:  return Operation.DIVIDE;
case DIVIDE: return Operation.TIMES;
}
}

5. Readability. I find a moderately sized switch statement easier to grok than an equivalent if / else if / else block.

When possible, avoid contrived examples for motivating usage. Instead, show where you (or someone else) used a switch & discuss why it was preferable.

The example that instantly comes to mind is Blackjack. See the code excerpt below for an extended example in C (even though it's C, the syntax will pretty much hold true for Java as well):

int cardValue(char card)
{
int aceValue = -1;

if (card == 'A')
{
do
{
printf("What value would you like Ace to be?\n");
printf("Type 1 or 11: ");
aceValue = GetInt();
} while (aceValue != 1 && aceValue != 11);
}

switch (card)
{
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'T':
case 'J':
case 'Q':
case 'K':
return 10;
case 'A':
return aceValue;
default:
return -1;
}
}


This function takes in a character corresponding to the card's value. I used a single char as the data type for each card, so I needed a function that took in a card's name (i.e. letter) and returned its value. Were I to design this again, I would probably reduce it down to one return statement and have a variable represent something like cardValue (and in that case I'd need to use break statements, which I currently omit thanks to return). That said, the switch statement is a clear example where you don't want a bunch of if-else statements. For the face cards that would be redundant. There's a nice mix of those cases that "fall through" and those that don't.

Using card games where cards share the same value is a fun, but realistic example for students to see the value of a switch statement.

I'll share one other short example where students have to implement a command-line calculator in C and used switch to identify which operation to perform. Here's the switch from there:

    switch (argv[2][0]) {
case 'x':
printf("%f\n", numOne * numTwo);
break;
case '/':
printf("%f\n", numOne / numTwo);
break;
case '+':
printf("%f\n", numOne + numTwo);
break;
case '-':
printf("%f\n", numOne - numTwo);
break;
case '%':
mod = numOne - (numTwo * modNum);
printf("%f\n", mod);
break;
default:
printf("Usage: <operation> must be x, /, +, -, or %%\n");
return 1;
}


With this example the clarity of the code is made much stronger by virtue of the case statements for each operation. From a readability perspective, it makes it clear how the operations are separated out by showing so visually.