EnumSet предназначен для хранения элементов Enum конкретного типа, который указывается при создании объекта.
Для хранения элементов EnumSet использует два объекта: RegularEnumSet<> и JumboEnumSet<>. Оба этих объекта имеют пакетную область видимости, т.е. пользователю они недоступны. Фабричный метод EnumSet.of() сам решает, в какой объект поместить переданные данные в зависимости от их количества.
В RegularEnumSet есть приватное поле elements типа long, использующееся в качестве битового вектора (bitvector). Каждый бит поля elements представляет собой элемент Enum: i-тый элемент будет храниться в i-товом бите. Это даёт возможность быстрого доступа к элементам EnumSet. Поскольку тип long составляет 64 бита, то в объекте RegularEnumSet может хранится 64 элемента.
JumboEnumSet позволяет хранить более 64 элементов, т.к. в качестве битового вектора использует массив элементов типа long.Т.о. первые 64 добавленных элемента будут храниться в нулевой ячейке массива, следующие 64 – в первой, и т.д. В целом JumboEnumSet работает так же, как RegularEnumSet с той лишь разницей, что ему приходится выполнять дополнительные вычисления для определения номера ячейки массива.
Поскольку элементы EnumSet хранятся в битовых векторах, все его методы используют арифметические операции побитового сдвига. Это позволяет производить вычисления очень быстро, а следовательно все базовые операции выполняются за константное время O(1).
По сравнению с остальными реализациями интерфейса Set, EnumSet работает быстрее и занимает меньше памяти за счет того, что хранит свои данные в битовых векторах. Поэтому, когда требуется хранить элементы Enum, рекомендуется использовать EnumSet.
enum Seasons {
SUMMER, WINTER, SPRING, AUTUMN;
}
EnumSet<Seasons> seasons = EnumSet.of(Seasons.SUMMER, Seasons.SPRING);
for (Seasons season : seasons) {
System.out.println(season);
}
/*
SUMMER
SPRING
*/
Хорошая статья о EnumSet.