Java Arena
Step 5 of 8

Enums: a fixed set of values

Some values can only be one of a few: a traffic light is red, yellow or green, a cup of coffee is small, medium or large. Module 17's TrafficLight challenge kept its color in a String, private String color;, and compared it with equals. That works as long as every String is spelled exactly right, but nothing stops a typo:

String light = "Green";
if (light.equals("green")) {
    System.out.println("Go");
} else {
    System.out.println("Stop");
}
Output
Stop

The capital G makes it another String, and neither javac nor the program notices anything wrong. An enum (short for enumerated type) is a type that lists every value it can have:

public enum Light {
    RED, YELLOW, GREEN
}
  • It's written like a class, with the word enum in place of class, in a file of its own, Light.java.
  • The values are called constants. They're separated by commas, and by custom written in capital letters.
  • A variable of type Light can hold one of these three, and nothing else (or null, like any object variable).
Main.java
public class Main {
    public static void main(String[] args) {
        Light light = Light.GREEN;
        System.out.println(light);
        if (light == Light.GREEN) {
            System.out.println("Go");
        }
        light = Light.RED;
        System.out.println(light == Light.GREEN);
    }
}
Light.java
public enum Light {
    RED, YELLOW, GREEN
}
Output
GREEN
Go
false
  • A constant is written with the enum's name and a dot: Light.GREEN.
  • Printing a constant prints its name.
  • Constants are compared with ==. Each constant is one object, made once, the first time the program uses the enum, so there's never a second GREEN, and == is right here, unlike for Strings. (equals gives the same answers.)

A typo is now javac's problem, not the user's:

Main.java
public class Main {
    public static void main(String[] args) {
        Light light = Light.GREN;
        System.out.println(light);
    }
}
Light.java
public enum Light {
    RED, YELLOW, GREEN
}
What javac prints
Main.java:3: error: cannot find symbol
        Light light = Light.GREN;
                           ^
  symbol:   variable GREN
  location: class Light
1 error

values(), name() and ordinal()

  • Light.values() returns an array of all the constants, in the order they're written in the enum. A for-each loop goes through it.
  • name() returns a constant's name as a String, such as "RED".
  • ordinal() returns a constant's position in the enum, counted from 0.
Main.java
public class Main {
    public static void main(String[] args) {
        for (Light light : Light.values()) {
            System.out.println(light.ordinal() + ": " + light.name().toLowerCase());
        }
        System.out.println(Light.values().length + " lights");
    }
}
Light.java
public enum Light {
    RED, YELLOW, GREEN
}
Output
0: red
1: yellow
2: green
3 lights

An enum is a type

An enum can be the type of a variable, a parameter, a return value, an instance variable or a list's elements, like any class. A method can check which constant it got:

Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println(canCross(Light.GREEN));
        System.out.println(canCross(Light.YELLOW));
    }

    public static boolean canCross(Light light) {
        return light == Light.GREEN;
    }
}
Light.java
public enum Light {
    RED, YELLOW, GREEN
}
Output
true
false

Java also has Light.valueOf("RED"), which gives the constant with that name. For a text that isn't a constant's name, it stops the program with an error, and part 11 covers handling errors like that.

Your task

Challenge 1 of 3

A traffic light in the US goes from green to yellow, from yellow to red, and from red back to green. That's the cycle of module 17's TrafficLight, this time with an enum in place of Strings. Light.java is ready. In Main.java, write the method next(Light light), which returns the light that comes after the one it's given. Compare the constants with ==. The check runs:

System.out.println(next(Light.GREEN));
System.out.println(next(Light.YELLOW));
System.out.println(next(Light.RED));

and expects:

YELLOW
RED
GREEN

Challenge 2

What does this program print?

Challenge 3

On a parade ground, a marching band faces north, east, south or west, and at the command "right face", everyone makes a quarter turn clockwise. Write:

  • in Direction.java, the enum Direction, with the constants NORTH, EAST, SOUTH and WEST, in that order (clockwise)
  • in Main.java, the method turnRight(Direction facing), which returns the direction after a quarter turn clockwise: north to east, east to south, south to west, and west back to north

main is a test drive, and it prints:

NORTH
EAST
SOUTH
WEST
NORTH