«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 Stream

Давайте посмотрим, как мы можем найти соответствующий 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() каждый раз, когда нам нужно получить соответствующее перечисление.

Также обратите внимание, что при таком подходе мы получаем необязательный\u003cPizzaStatus\u003e вместо непосредственного экземпляра PizzaStatus.

3. Использование Map

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

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

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

Кроме того, метод values ​​класса Enum предоставляет все значения перечисления. В статическом блоке мы перебираем массив значений 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.