Java Arena
Step 3 of 5

switch on strings and enums

Strings

Since Java 7, a switch can choose by a String. The labels are String literals, and a label matches when the String equals it, exactly: capitals count, and so do spaces. A radio reads commands:

Scanner scanner = new Scanner(System.in);
int volume = 5;
while (true) {
    String command = scanner.nextLine();
    if (command.equals("off")) {
        break;
    }
    switch (command) {
        case "louder" -> volume++;
        case "quieter" -> volume--;
        case "status" -> System.out.println("Volume " + volume);
        default -> System.out.println("Unknown command: " + command);
    }
}
System.out.println("Radio off at volume " + volume);
Input
louder
louder
status
Quieter
off
Output
Volume 7
Unknown command: Quieter
Radio off at volume 7

Quieter with a capital Q isn't quieter, so it goes to default. A program that should take both can switch on command.toLowerCase().

The check for off stays an if before the switch, and here's why: inside a switch, break ends the switch, not the loop around it. A break in a case would leave the switch and go on reading commands.

One more thing to know: a switch on a String that is null throws a NullPointerException, as calling a method on it would.

Enums

A switch on an enum (module 39) uses the constants' names as labels. A cinema's tickets come in three kinds:

Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println(price(Ticket.CHILD));
        System.out.println(price(Ticket.ADULT) + price(Ticket.SENIOR));
    }

    public static int price(Ticket ticket) {
        return switch (ticket) {
            case CHILD -> 6;
            case ADULT -> 12;
            case SENIOR -> 8;
        };
    }
}
Ticket.java
public enum Ticket {
    CHILD, ADULT, SENIOR
}
Output
6
20
  • A label is the constant's name alone, case CHILD, not case Ticket.CHILD: the switch already knows the enum. (Since Java 21 the long name is allowed too, but the short one is the custom.)
  • This switch expression has no default, and it doesn't need one: an enum has only the values it lists, and the three cases cover them all, so javac knows the switch always gives a value.

When the enum grows

Leaving out default pays off when someone adds a constant. Say the cinema starts selling STUDENT tickets:

Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println(price(Ticket.STUDENT));
    }

    public static int price(Ticket ticket) {
        return switch (ticket) {
            case CHILD -> 6;
            case ADULT -> 12;
            case SENIOR -> 8;
        };
    }
}
Ticket.java
public enum Ticket {
    CHILD, ADULT, SENIOR, STUDENT
}
What javac prints
Main.java:7: error: the switch expression does not cover all possible input values
        return switch (ticket) {
               ^
1 error

javac points at every switch expression that has no case for STUDENT, and once each has one, the program is complete again. With default -> 0; in the switch, it would have compiled, and every student would have got in for free without anyone noticing. So for an enum, list every constant and leave default out.

A switch statement on an enum, with arrows or with colons, may leave constants out, like a switch statement on an int.

Your task

Challenge 1 of 3

A drinks machine is run by commands, one per line, until the line quit. It keeps a credit of coins, at first 0. Write the switch on the command, so that:

  • coin adds one coin to the credit and prints the credit, like Credit: 2
  • tea costs 2 coins: if the credit is at least 2, it takes them and prints Here is your tea; otherwise it prints Tea costs 2 coins
  • refund prints the coins given back, like Returned 3 coins, and sets the credit to 0
  • any other command prints Unknown command: and the command

The loop and the check for quit are written. With this input:

Input
coin
tea
coin
coin
coin
tea
refund
dance
quit

the program prints:

Credit: 1
Tea costs 2 coins
Credit: 2
Credit: 3
Credit: 4
Here is your tea
Returned 2 coins
Unknown command: dance
Bye

Challenge 2

A car wash charges by the program. Wash.java has the enum Wash, with the constants BASIC, FOAM and DELUXE. In Main.java, write the method washPrice(Wash wash), which returns the price in euros with a switch expression: 4 for BASIC, 7 for FOAM and 12 for DELUXE. Cover every constant, and leave out default. The check runs System.out.println(washPrice(Wash.FOAM));, which prints:

7

Challenge 3

A puzzle game sets the player's lives and time limit by the difficulty. The designer has just added a fourth difficulty, EXPERT, to the enum in Difficulty.java, and now Main.java doesn't compile: javac says that the switch expressions don't cover all possible input values. Press Run to see it. Fix both methods: an expert game gives 1 life and 60 seconds. Don't add a default. The check runs:

System.out.println("Lives: " + startingLives(Difficulty.EXPERT) + ", time: " + timeLimit(Difficulty.EXPERT) + " seconds");

which prints:

Lives: 1, time: 60 seconds