Java Notes

Enums

Problem: How to represent a set of named constant values. First we'll look at the "old" Java solution, then see how Java 5 enums substantially improve the situation.

Older, but common, solution

Just define a number of public static final int constants. For example:

//... Constants to represent possible shapes.
public static final int RECTANGLE = 0;
public static final int CIRCLE    = 1;
public static final int LINE      = 2;
...
int drawing = RECTANGLE;   // But any int could be assigned.

These values can then be assigned to an integer variable, and can be used in switch statements. This style is useful, but is not a great solution.

Defining an enum type

An enum type is a kind of class definition. The possible enum values are listed in the curly braces, separated by commas. By convention the value names are in upper case.

public enum Shape { RECTANGLE, CIRCLE, LINE }

Declaring enum variables and using enum values

The enum class name can be use like any other class type in declarations. Usually enum values must be prefixed with the enum type name.

Shape drawing = Shape.RECTANGLE;   // Only a Shape value can be assigned.

Printing enum values

The enum class has a toString() method defined that returns the unqualified string version of the value. This means that it's easy to print these values without any special conversion effort.

System.out.println(drawing);    // Prints RECTANGLE

Looping over all enum values with foreach loop

The static values() method of an enum type returns an array of the enum values. The foreach loop is a good way to go over all of them.

//... Loop over all values.
for (Shape shp : Shape.values()) {
    System.out.println(shp);       // Prints RECTANGLE, CIRCLE, ...
}

Switch statement

The switch statement was enhanced to allow a convenient use of enums. Note that the case values don't have to be qualified with the enum class name, which can be determined from the switch control value.

switch (drawing) {
    case RECTANGLE: g.drawRect(x, y, width, height);
                    break;
    case CIRCLE   : g.drawOval(x, y, width, height);
                    break;
    case LINE     : g.drawLine(x, y, x + width, y + height);
                    break;
}

Getting an integer equivalent of an enum value

Each enum value in an enum class has an associated default value, starting with zero for the first value and incrementing by one for each additional value. This may be accessed with the ordinal() method.

System.out.println(drawing.ordinal());     // Prints 0 for RECTANGLE.

Input

The valueOf() method can be used to convert a string value to an enum value. Here is an example of reading in a Shape value from a Scanner object in.

drawing = Shape.valueOf(in.next());

Defining additional fields, methods, and constants for your enum type

Methods can be defined for an enum class, including defining a different method body for each of the constants. See the Sun article for examples of this. If you are using switch statements with cases for each of the enum constants, consider putting the code into the enum class.

Related data structure classes: EnumSet and EnumMap

The java.util.EnumSet class provides an efficient implementation of sets of enums as bit maps, or powersets as they were called in Pascal. EnumSet can also generate an Iterable for use with subsets in the for-each statement.

java.util.EnumMap provides an efficient implementation of a map for enums based on an array.

Further reading