Java EnumSet: создание, операции и советы по производительности
Java EnumSet
Это руководство проведёт вас через создание, манипуляцию и оптимизацию коллекций Java EnumSet с практическими примерами кода и лучшими практиками.
Класс EnumSet — это высокопроизводительная реализация множества, разработанная исключительно для типов enum. Он реализует интерфейс java.util.Set и также наследует Cloneable и Serializable, делая его универсальным и эффективным.
Прежде чем погружаться в EnumSet, убедитесь, что вы комфортно работаете с Java enum, так как множество тесно связано с одним типом enum.
Создание EnumSet
В отличие от других реализаций множеств, EnumSet не предоставляет публичных конструкторов. Вместо этого используются статические фабричные методы для построения множества.
1. Использование EnumSet.allOf()
Метод allOf() создаёт множество, содержащее каждую константу указанного типа enum.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.allOf(Size.class);
System.out.println("EnumSet: " + sizes);
}
}
Вывод
EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE]
2. Использование EnumSet.noneOf()
Создаёт пустое множество, которое может содержать только значения указанного типа enum.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.noneOf(Size.class);
System.out.println("Empty EnumSet: " + sizes);
}
}
Вывод
Empty EnumSet: []
Примечание: Полученное множество принимает только константы Size, так как было инстанцировано с Size.class.
3. Использование EnumSet.range()
Строит множество, содержащее все константы enum от нижней границы до верхней, включительно.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.range(Size.MEDIUM, Size.EXTRALARGE);
System.out.println("EnumSet: " + sizes);
}
}
Вывод
EnumSet: [MEDIUM, LARGE, EXTRALARGE]
4. Использование EnumSet.of()
Создаёт множество, содержащее одну или несколько конкретных констант enum.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes1 = EnumSet.of(Size.MEDIUM);
System.out.println("EnumSet1: " + sizes1);
EnumSet<Size> sizes2 = EnumSet.of(Size.SMALL, Size.LARGE);
System.out.println("EnumSet2: " + sizes2);
}
}
Вывод
EnumSet1: [MEDIUM] EnumSet2: [SMALL, LARGE]
Частые операции над EnumSet
Добавление элементов
add()— вставляет одну константу enum.addAll()— объединяет другую коллекцию того же типа enum.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> all = EnumSet.allOf(Size.class);
EnumSet<Size> selected = EnumSet.noneOf(Size.class);
selected.add(Size.MEDIUM);
System.out.println("After add(): " + selected);
selected.addAll(all);
System.out.println("After addAll(): " + selected);
}
}
Вывод
After add(): [MEDIUM] After addAll(): [SMALL, MEDIUM, LARGE, EXTRALARGE]
Обратите внимание, что addAll() принимает любой Collection<Size>, включая списки или множества, если они содержат тот же тип enum.
Итерация элементов
Используйте Iterator для обхода множества:
import java.util.EnumSet;
import java.util.Iterator;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.allOf(Size.class);
Iterator<Size> it = sizes.iterator();
System.out.print("EnumSet: ");
while (it.hasNext()) {
System.out.print(it.next() + ", ");
}
}
}
Вывод
EnumSet: SMALL, MEDIUM, LARGE, EXTRALARGE,
Удаление элементов
remove()— удаляет конкретную константу.removeAll()— очищает множество, когда передано само себе.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.allOf(Size.class);
System.out.println("EnumSet: " + sizes);
boolean removed = sizes.remove(Size.MEDIUM);
System.out.println("Is MEDIUM removed? " + removed);
boolean cleared = sizes.removeAll(sizes);
System.out.println("Are all elements removed? " + cleared);
}
}
Вывод
EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE] Is MEDIUM removed? true Are all elements removed? true
Дополнительные вспомогательные методы
| Метод | Описание |
|---|---|
copyOf() | Создаёт новый EnumSet, содержащий те же элементы. |
contains() | Проверяет, присутствует ли конкретная константа. |
isEmpty() | Возвращает true, если множество не имеет элементов. |
size() | Возвращает количество элементов. |
clear() | Удаляет все элементы. |
Cloneable и Serializable
EnumSet реализует Cloneable, позволяя создавать поверхностную копию через clone(). Он также реализует Serializable, позволяя безопасную передачу по сети или сохранение на диск.
Зачем использовать EnumSet?
Поскольку EnumSet хранит свои значения как битовый вектор, операции add, remove и contains выполняются за постоянное время с минимальными накладными расходами по памяти. JVM уже знает точный набор возможных констант для данного enum, что делает EnumSet гораздо более эффективным, чем общие реализации вроде HashSet или TreeSet.
На практике выбирайте EnumSet, когда вам нужно высокопроизводительное множество значений enum.
java
- Освоение операторов Java: типы, синтаксис и практические примеры
- Комментарии в Java: типы, использование и лучшие практики
- Освоение улучшенного цикла for в Java: синтаксис, примеры и лучшие практики
- Освоение строк в Java: создание, методы и лучшие практики
- Анонимные внутренние классы в Java: определение, синтаксис и практические примеры
- Перечисления (Enums) в Java: полное руководство по enum и enum-классам
- Конструкторы в Java Enums: объяснение с практическим примером
- Try-with-resources в Java: автоматическое управление ресурсами
- Аннотации в Java: типы, размещение и практические примеры
- Assertions в Java: практическое руководство по обнаружению багов и обеспечению надежности кода