Since Version 5.0 Java has offered the ability to define *enums* (short for *enumerated types*). An *enum* is a type that has a fixed list of possible values, which is specified when the *enum* is created. In some ways, an *enum* is similar to the *boolean* data type, which has **true** and **false** as its only possible values. However, *boolean* is a primitive type, while an enum is not.

The definition of an enum type has the form:

enum enum-type-name { list-of-enum-values }

This definition cannot be inside a subroutine. You can place it outside the main() routine of the program. The enum-type-name can be any simple identifier. This identifier becomes the name of the *enum* type, in the same way that “boolean” is the name of the *boolean* type and “String” is the name of the *String* type. Each value in the list-of-enum-values must be a simple identifier, and the identifiers in the list are separated by commas. For example, here is the definition of an* enum* type named *Season* whose values are the names of the four seasons of the year:

enum Season { SPRING, SUMMER, AUTUMN, WINTER }

By convention, *enum* values are given names that are made up of upper case letters, but that is a style guideline and not a syntax rule. *Enum* values are not variables. Each value is a constant that always has the same value. In fact, the possible values of an *enum* type are usually referred to as **enum constants.**

Suppose that *E* is an enumerated type. Since *E* is a class, it is possible to create objects of type *TreeSet<E>* and *HashSet<E>*. However, because enums are so simple, trees and hash tables are not the most efficient implementation for sets of enumerated type values. Java provides the class *java.util.EnumSet* as an alternative way to create such sets.

Sets of enumerated type values are created using static methods in the class *EnumSet.* For example, if e1, e2, and e3 are values belonging to the enumerated type *E*, then the method

EnumSet.of( e1, e2, e3 )

creates and returns a set of type *EnumSet<E>* that contains exactly the elements e1, e2, and e3. The set implements the interface *Set<E>*, so all the usual set and collection operations are available. The implementation of these operations is very efficient. The implementation uses what is called a** bit vector.** A bit is a quantity that has only two possible values, zero and one. A set of type *EnumSet<E>* is represented by a bit vector that contains one bit for each *enum* constant in the enumerated type *E*; the bit corresponding to the *enum* constant e is 1 if e is a member of the set and is 0 if e is not a member of the set. The bit vectors for two sets of type *EnumSet<E>* can be very easily combined to represent such operations as the union and intersection of two sets.

The bit vector representation is feasible for *EnumSets*, but not for other sets in Java, because an enumerated type contains only a small finite number of enum constants.

The function *EnumSet.of *can be used with any positive number of parameters. All the parameters must be values of the same enumerated type. Null values are not allowed. An *EnumSet* cannot contain the value **null** – any attempt to add null to an *EnumSet* will result in a *NullPointerException*.

There is also a function *EnumSet.range(e1,e2)* that returns an *EnumSet* consisting of the enum constants between e1 and e2, inclusive. The ordering of enum constants is the same as the order in which they are listed in the definition of the *enum*. In *EnumSet.range(e1,e2)*, e1 and e2 must belong to the same enumerated type, and e1 must be less than or equal to e2.

If *E* is an enum, then *EnumSet.allOf(E.class)* is a set that contains all values of type *E*. *EnumSet.noneOf(E.class)* is an empty set, a set of *typeEnumSet<E>* that contains no elements at all. Note that in *EnumSet.allOf(E.class)* and *EnumSet.noneOf(E.class)*, the odd-looking parameter represents the enumerated type class itself. If *eset* is a set of type *EnumSet<E>*, then *EnumSet.complementOf(eset)* is a set that contains all the enum constants of *E* that are **not** in *eset*.

As an example, consider a program that keeps schedules of events. The program must keep track of repeating events that happen on specified days of the week. For example, an event might take place only on weekdays, or only on Wednesdays and Fridays. In other words, associated with the event is the **set** of days of the week on which it takes place. This information can be represented using the enumerated type:

enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }

The days of the week on which an event takes place would then be a value of type *EnumSet<Day>*. An object of type *RepeatingEvent* would have an instance variable of type *EnumSet<Day>* to hold this information. An event that takes place on Wednesdays and Fridays would have the associated set:

EnumSet.of( Day.WEDNESDAY, Day.FRIDAY )

We could define some common sets of *Days* as

EnumSet<Day> weekday = EnumSet.range( Day.MONDAY, Day.FRIDAY ); EnumSet<Day> weekend = EnumSet.complementOf( weekday ); EnumSet<Day> everyday = EnumSet.allOf( Day.class );

*EnumSets *are often used to specify sets of “options” that are to be applied during some type of processing. For example, a program that draws characters in fancy fonts might have various options that can be applied. Let’s say that the options are bold, italic, underlined, strikethrough, and boxed. Note that we are assuming that options can be combined in arbitrary ways. For example, you can have italic, boxed, underlined characters. This just means that we need to keep track of a **set** of options. If the options are represented by the enumerated type:

enum FontOption { BOLD, ITALIC, UNDERLINED, STRIKETHROUGH, BOXED }

then a set of options is represented by a value of type *EnumSet<FontOption>*. Suppose that options is a variable of this type that represents the set of options that are currently being applied by the program. Then we can do things like:

– Turn off all options.*options = EnumSet.noneOf( FontOption.class )*– Use bold, with no other options.*options =**EnumSet.of( FontOption.BOLD )*– Add bold to any options that are already on.*options.add( FontOption.BOLD )*– Turn underlining off (if it’s on).**options.remove( FontOption.UNDERLINED )**

This is a nice, safe way to work with sets of options. Applications like this are one of the major reasons that enumerated types were introduced.

**Next: Maps**