EnumSet in Java

Naveen AnamaneniUpdated · 4 min read

EnumSet in Java is a specialized Set implementation that is used to store values of a single enum type. Inside, it represents the set as a sequence of bits, one bit per enum constant, so it is extremely fast and uses very little memory. Elements are always kept in the order the constants are declared in the enum. In this lesson, you will learn how to create and use an EnumSet.

Declaration

Declaration
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
        implements Cloneable, Serializable

EnumSet is abstract and has no public constructor. You create one with its static factory methods.

Features of EnumSet

  • Only enum values, all from the same enum type.
  • Declaration order: elements always come out in the order of the enum constants.
  • No null: adding null throws NullPointerException.
  • Very fast: operations are bit operations, much faster than HashSet.
  • Not synchronized.

Factory Methods

MethodDescription
EnumSet.of(e1, e2, ...)It creates a set containing the given constants.
EnumSet.allOf(Type.class)It creates a set containing all constants of the enum.
EnumSet.noneOf(Type.class)It creates an empty set for the enum.
EnumSet.range(from, to)It creates a set of the constants from from to to, both included.
EnumSet.complementOf(set)It creates a set of all constants not in the given set.
EnumSet.copyOf(collection)It creates a set from a collection of constants.

Example: Working Days and Weekends

Let's see an example using the days of the week.

EnumSetDemo.java▶ Try it
import java.time.DayOfWeek;
import java.util.EnumSet;
 
public class EnumSetDemo {
    public static void main(String[] args) {
        EnumSet<DayOfWeek> weekend =
            EnumSet.of(DayOfWeek.SUNDAY, DayOfWeek.SATURDAY);
        EnumSet<DayOfWeek> workdays = EnumSet.complementOf(weekend);
        EnumSet<DayOfWeek> midweek =
            EnumSet.range(DayOfWeek.TUESDAY, DayOfWeek.THURSDAY);
 
        System.out.println("Weekend:  " + weekend);
        System.out.println("Workdays: " + workdays);
        System.out.println("Midweek:  " + midweek);
        System.out.println("Is FRIDAY a workday? "
            + workdays.contains(DayOfWeek.FRIDAY));
    }
}
Output
Weekend:  [SATURDAY, SUNDAY]
Workdays: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
Midweek:  [TUESDAY, WEDNESDAY, THURSDAY]
Is FRIDAY a workday? true

Explanation: SUNDAY was listed first in of, but the set prints SATURDAY first because DayOfWeek declares SATURDAY before SUNDAY. complementOf gives every other day, and range includes both ends.

Example: Permissions as Flags

EnumSet is the modern replacement for "bit flags" stored in an int:

Permissions.java▶ Try it
import java.util.EnumSet;
 
public class Permissions {
    enum Permission { READ, WRITE, DELETE, SHARE }
 
    public static void main(String[] args) {
        EnumSet<Permission> navika = EnumSet.noneOf(Permission.class);
        navika.add(Permission.READ);
        navika.add(Permission.SHARE);
 
        EnumSet<Permission> admin = EnumSet.allOf(Permission.class);
 
        System.out.println("Navika: " + navika);
        System.out.println("Admin:  " + admin);
        System.out.println("Navika can delete? "
            + navika.contains(Permission.DELETE));
        System.out.println("Admin has all of Navika's? "
            + admin.containsAll(navika));
    }
}
Output
Navika: [READ, SHARE]
Admin:  [READ, WRITE, DELETE, SHARE]
Navika can delete? false
Admin has all of Navika's? true

Explanation: noneOf starts with an empty set, and permissions are added one by one. allOf gives every permission. Checking a permission is a single bit test, which is very fast and reads clearly.

Common Mistakes

Trying new EnumSet<>(). It's abstract; use noneOf, of or allOf.

Adding null. It throws NullPointerException.

Calling copyOf on an empty plain collection. It can't tell the enum type and throws IllegalArgumentException; use noneOf for empty sets.

Practice

  1. Easy: Create an enum Size { S, M, L, XL, XXL } and print all sizes from M to XL using range.
  2. Harder: Model a pizza order with an EnumSet<Topping>. Print the toppings chosen and the toppings not chosen.

Quick check: EnumSet

4 questions
1What can an EnumSet store?
2In what order does an EnumSet iterate?
3How do you create an empty EnumSet?
4Does EnumSet.range(A, C) include C?

Key Takeaways

Was this tutorial helpful?

Lesson 277 of 482