Как задать начальное значение enum в Java: подробный гайд

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Напрямую присвоить начальные значения в Java enum невозможно. Однако можно установить индивидуальные значения с помощью конструкторов:

Java
Скопировать код
public enum Статус {
    НАЧАЛО(100), // Начнём именно с 100-го!
    СЕРЕДИНА(200), // Достижение середины пути.
    КОНЕЦ(300); // Завершающий этап – 300.

    private final int код;

    Статус(int код) {
        this.код = код;
    }

    public int получитьКод() {
        return код;
    }
}

Можно получить 100, вызвав Статус.НАЧАЛО.получитьКод(). В Java enum используют для определения именованных констант, а не для задания числовых последовательностей.

Пользовательские значения Enum: инструкции

В Java enum — это фактически классы, а не просто наборы номеров. Рассмотрим примеры, которые показывают, как улучшить работу с перечислениями.

Создание Enum с использованием конструкторов и полей

Добавление конструктора, приватных полей и методов превращает перечисление в полноценный класс:

Java
Скопировать код
public enum Роль {
    АДМИН(1), // Администратор системы.
    ПОЛЬЗОВАТЕЛЬ(2), 
    ГОСТЬ(3);

    private final int idРоли;

    Роль(int idРоли) {
        this.idРоли = idРоли;
    }

    public int получитьIdРоли() {
        return idРоли;
    }
}

Вызывая Роль.АДМИН.получитьIdРоли(), получаем 1, используя пользовательские значения.

Использование статических карт и метода Ordinal

Эффективным может быть использование static Map для сопоставления констант с пользовательскими значениями:

Java
Скопировать код
import java.util.Map;
import java.util.HashMap;

public enum Цвет {
    КРАСНЫЙ, // Огненный цвет.
    ЗЕЛЕНЫЙ, // Это цвет природы.
    СИНИЙ; // Глубина и спокойствие.

    private static final Map<Цвет, Integer> карта = new HashMap<>();
    static {
        карта.put(КРАСНЫЙ, 0xFF0000);
        карта.put(ЗЕЛЕНЫЙ, 0x00FF00);
        карта.put(СИНИЙ, 0x0000FF);
    }

    public int получитьКодЦвета() {
        return карта.get(this);
    }
}

Такой метод предоставляет возможность использовать таблицу поиска для определения значения каждого элемента.

Оператор Switch для условной обработки

switch — прекрасный инструмент для работы с Enums:

Java
Скопировать код
public int получитьПриоритет(СтатусЗадачи статус) {
    switch (статус) {
        case СРОЧНО: return 1; // Наивысший приоритет.
        case ВЫСОКИЙ: return 2; 
        case СРЕДНИЙ: return 3; 
        case НИЗКИЙ: return 4; // Задача может подождать.
        default: return 5;
    }
}

switch позволяет лаконично обработать различные случаи для значений enum.

TreeMap для упорядоченного сопоставления

Если важна последовательность, на помощь приходит TreeMap:

Java
Скопировать код
import java.util.TreeMap;

public enum Приоритет {
    НИЗКИЙ, // Работа, не требующая срочного внимания.
    СРЕДНИЙ, // Обычная скорость работы.
    ВЫСОКИЙ; // Максимум внимания.

    private static final TreeMap<Приоритет, Integer> карта = new TreeMap<>();
    static {
        карта.put(НИЗКИЙ, 1);
        карта.put(СРЕДНИЙ, 2);
        карта.put(ВЫСОКИЙ, 3);
    }

    public int получитьУровень() {
        return карта.get(this);
    }
}

Метод Приоритет.ВЫСОКИЙ.получитьУровень() возвращает 3.

Централизованный метод для извлечения значений

Общий статический метод – это удобный способ извлечения значений для элементов enum:

Java
Скопировать код
public enum Операция {
    ДОБАВИТЬ, // Сложение элементов.
    ВЫЧЕСТЬ, // Вычитание значений.
    УМНОЖИТЬ, // Умножение чисел.
    РАЗДЕЛИТЬ; // Вычисление частного.

    public static Операция получитьОперациюПоИндексу(int индекс) {
        return values()[индекс];
    }
}

Операция.получитьОперациюПоИндексу(1) вернёт операцию ВЫЧЕСТЬ.

Использование порядковых значений для пользовательских значений

Метод ordinal может служить основой для пользовательских значений:

Java
Скопировать код
public enum Шаг {
    ОДИН, // Начинаем путь.
    ДВА, // Второй этап пути.
    ТРИ, // Третий этап развития.
    ЧЕТЫРЕ; // Завершающий этап задачи.

    private static final int БАЗА = 10;

    public int получитьПользовательскоеЗначение() {
        return БАЗА + ordinal();
    }
}

Значения начинаются с 10 при вызове Шаг.ОДИН.получитьПользовательскоеЗначение().

Визуализация

Инициализация начального значения enum напоминает процесс прицепления вагонов к поезду:

Markdown
Скопировать код
Обычный состав Enum (🚂): [ВАГОН_1, ВАГОН_2, ВАГОН_3]

Начать с ВАГОН_3 нам не удастся, ведь Java такого не позволит!

Java
Скопировать код
/* Объявление экспресса Enum */
enum Статус {
    ВАГОН_3(3), // Java не даст начать именно с этого значения.
    ВАГОН_1(1),
    ВАГОН_2(2);    
}

В Java порядок следования enum определён местом его объявления:

Markdown
Скопировать код
Станция Java Enum (🛤️): [🚂ВАГОН_1, ВАГОН_2, ВАГОН_3]

Перестановки и пропуски мест в очереди недопустимы. 🚫 🚂

Улучшенные паттерны в Java Enums

Добавим несколько сложных приёмов для расширения возможностей перечислений.

Кэширование значений для экономии памяти

Использование кэша способствует экономии памяти и оптимизации выполнения программы, так как предотвращает создание новых объектов:

Java
Скопировать код
public enum Планета {
    МЕРКУРИЙ(3.303e+23), // Очень маленькая планета.
    ВЕНЕРА(4.869e+24), // Огромное давление.
    ЗЕМЛЯ(5.976e+24); // Наш общий дом.

    private final double масса;
    private static final Map<Планета, Double> картаМасс = new HashMap<>();

    static {
        for (Планета планета : values()) {
            картаМасс.put(планета, планета.масса);
        }
    }

    Планета(double масса) {
        this.масса = масса;
    }

    public double получитьМассу() {
        return картаМасс.get(this);
    }
}

Этот метод отлично подходит для неизменных значений, которые часто используются в запросах.

Паттерн Singleton в действии

Enums – это идеальная реализация шаблона Singleton благодаря встроенному управлению созданием экземпляров и удобству использования при сериализации:

Java
Скопировать код
public enum Singleton {
    INSTANCE; // Единственный и неповторимый.

    private ValuableResource resource;

    Singleton() {
        resource = new ValuableResource();
    }

    public ValuableResource getResource() {
        return resource;
    }
}

Вызов Singleton.INSTANCE.getResource() обеспечивает единственную инициализацию ресурса.

Динамическое поведение с помощью анонимных классов

Анонимные классы позволяют определить различное поведение для каждого элемента enum:

Java
Скопировать код
public enum Calculator {
    ДОБАВИТЬ {
        @Override
        public int calculate(int x, int y) {
            return x + y; // Операция сложения.
        }
    },
    ВЫЧЕСТЬ {
        @Override
        public int calculate(int x, int y) {
            return x – y; // Операция вычитания.
        }
    };

    public abstract int calculate(int x, int y);
}

Каждая константа enum имеет свою реализацию и на её основе определяет своё поведение.

Полезные материалы

  1. Типы Enum в Java — официальная документация Java про перечисления Enum.
  2. Enum в Java – GeeksforGeeks — подробное описание перечислений Enum в Java с примерами.
  3. Является ли хорошей практикой использование порядковых значений enum? – Stack Overflow — обсуждение лучших практик применения enum.
  4. Значения Enum в Java – Baeldung — рассмотрение использования методов hashCode() и equals() для enum.
  5. Тип Enum – Stack Overflow Documentation — обзор Enum в Java.
  6. Итерация по Enum в Java – DZone — обсуждение способов итерации по значениям Enum в Java.
  7. Лучшие практики использования Enum в Java – Stackify — обзор лучших практик при работе с перечислениями.