Перейти к основному содержимому

Приведение к Enum в Java

· 3 мин. чтения

1. Обзор

В этом руководстве мы кратко рассмотрим различные способы приведения типа int к значению перечисления в Java. Хотя прямого способа приведения не существует, есть несколько способов приблизиться к нему.

2. Использование значений Enum # ``

Во-первых, давайте посмотрим, как мы можем решить эту проблему, используя метод значений Enum `` .

Начнем с создания перечисления PizzaStatus , определяющего статус заказа на пиццу:

public enum PizzaStatus {
ORDERED(5),
READY(2),
DELIVERED(0);

private int timeToDelivery;

PizzaStatus (int timeToDelivery) {
this.timeToDelivery = timeToDelivery;
}

// Method that gets the timeToDelivery variable.
}

Мы связываем каждое постоянное значение перечисления с полем timeToDelivery . При определении константных перечислений мы передаем поле timeToDelivery конструктору.

Метод статических значений возвращает массив, содержащий все значения перечисления в порядке их объявления. Следовательно, мы можем использовать целочисленное значение timeToDelivery , чтобы получить соответствующее значение перечисления:

int timeToDeliveryForOrderedPizzaStatus = 5;

PizzaStatus pizzaOrderedStatus = null;

for (PizzaStatus pizzaStatus : PizzaStatus.values()) {
if (pizzaStatus.getTimeToDelivery() == timeToDeliveryForOrderedPizzaStatus) {
pizzaOrderedStatus = pizzaStatus;
}
}

assertThat(pizzaOrderedStatus).isEqualTo(PizzaStatus.ORDERED);

Здесь мы используем массив, возвращаемый функцией PizzaStatus.values() , чтобы найти соответствующее значение на основе свойства timeToDelivery .

Однако такой подход достаточно многословен. Кроме того, это также неэффективно, так как каждый раз, когда мы хотим получить соответствующий PizzaStatus , нам нужно перебирать PizzaStatus.values() .

2.1. Использование потока Java 8

Давайте посмотрим, как мы можем найти соответствующий PizzaStatus, используя подход Java 8:

int timeToDeliveryForOrderedPizzaStatus = 5;

Optional<PizzaStatus> pizzaStatus = Arrays.stream(PizzaStatus.values())
.filter(p -> p.getTimeToDelivery() == timeToDeliveryForOrderedPizzaStatus)
.findFirst();

assertThat(pizzaStatus).hasValue(PizzaStatus.ORDERED);

Этот код выглядит более лаконичным, чем тот, в котором используется цикл for . Тем не менее, мы перебираем PizzaStatus.values() каждый раз, когда нам нужно получить соответствующее перечисление.

Также обратите внимание, что при таком подходе мы получаем Optional<PizzaStatus> вместо непосредственного экземпляра PizzaStatus .

3. Использование карты

Далее воспользуемся структурой данных Java Map вместе с методом values для получения значения перечисления, соответствующего времени доставки целочисленного значения.

В этом подходе метод values вызывается только один раз при инициализации карты . Кроме того, поскольку мы используем карту, нам не нужно перебирать значения каждый раз, когда нам нужно получить значение перечисления, соответствующее времени доставки.

Мы используем статическую карту timeToDeliveryToEnumValuesMapping внутри, которая обрабатывает отображение времени для доставки в соответствующее значение перечисления.

Кроме того, метод values класса Enum предоставляет все значения перечисления. В статическом блоке мы перебираем массив значений перечисления и добавляем их на карту вместе с соответствующим временем для доставки целочисленного значения в качестве ключа:

private static Map<Integer, PizzaStatus> timeToDeliveryToEnumValuesMapping = new HashMap<>();

static {
for (PizzaStatus pizzaStatus : PizzaStatus.values()) {
timeToDeliveryToEnumValuesMapping.put(
pizzaStatus.getTimeToDelivery(),
pizzaStatus
);
}
}

Наконец, мы создаем статический метод, который принимает целое число timeToDelivery в качестве параметра. Этот метод возвращает соответствующее значение перечисления, используя статическую карту timeToDeliveryToEnumValuesMapping :

public static PizzaStatus castIntToEnum(int timeToDelivery) {
return timeToDeliveryToEnumValuesMapping.get(timeToDelivery);
}

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

4. Вывод

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

Как всегда, все эти примеры кода доступны на GitHub .