Приведите Int для перечисления в Java - PullRequest
308 голосов
/ 04 мая 2011

Как правильно преобразовать Int в перечисление в Java, используя следующее перечисление?

public enum MyEnum
{
    EnumValue1,
    EnumValue2
}


MyEnum enumValue = (MyEnum) x; //Doesn't work???

Ответы [ 17 ]

554 голосов
/ 04 мая 2011

Попробуйте MyEnum.values()[x], где x должно быть 0 или 1, т.е. действительный порядковый номер для этого перечисления.

Обратите внимание, что в Java перечисления на самом деле являются классами (и значения перечисления, таким образом, являются объектами), и поэтому вы не можете привести int или даже Integer к перечислению.

152 голосов
/ 06 января 2012

MyEnum.values()[x] - дорогостоящая операция.Если производительность вызывает беспокойство, вы можете сделать что-то вроде этого:

public enum MyEnum {
    EnumValue1,
    EnumValue2;

    public static MyEnum fromInteger(int x) {
        switch(x) {
        case 0:
            return EnumValue1;
        case 1:
            return EnumValue2;
        }
        return null;
    }
}
43 голосов
/ 08 января 2013

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

public enum A
{
        B(0),
        C(10),
        None(11);
        int id;
        private A(int i){id = i;}

        public int GetID(){return id;}
        public boolean IsEmpty(){return this.equals(A.None);}
        public boolean Compare(int i){return id == i;}
        public static A GetValue(int _id)
        {
            A[] As = A.values();
            for(int i = 0; i < As.length; i++)
            {
                if(As[i].Compare(_id))
                    return As[i];
            }
            return A.None;
        }
}
28 голосов
/ 03 ноября 2015

Вы можете попробовать вот так.
Создать класс с идентификатором элемента.

      public Enum MyEnum {
        THIS(5),
        THAT(16),
        THE_OTHER(35);

        private int id; // Could be other data type besides int
        private MyEnum(int id) {
            this.id = id;
        }

        public static MyEnum fromId(int id) {
                for (MyEnum type : values()) {
                    if (type.getId() == id) {
                        return type;
                    }
                }
                return null;
            }
      }

Теперь выберите этот Enum, используя id как int.

MyEnum myEnum = MyEnum.fromId(5);
19 голосов
/ 19 декабря 2012

Я кеширую значения и создаю простой метод статического доступа:

public static enum EnumAttributeType {
    ENUM_1,
    ENUM_2;
    private static EnumAttributeType[] values = null;
    public static EnumAttributeType fromInt(int i) {
        if(EnumAttributeType.values == null) {
            EnumAttributeType.values = EnumAttributeType.values();
        }
        return EnumAttributeType.values[i];
    }
}
9 голосов
/ 04 мая 2011

Это не то, что обычно делается, поэтому я бы пересмотрел. Но, сказав это, основными операциями являются: int -> enum с использованием EnumType.values ​​() [intNum] и enum -> int с использованием enumInst.ordinal ().

Однако, поскольку любая реализация values ​​() не имеет другого выбора, кроме как предоставить вам копию массива (массивы java никогда не доступны только для чтения), вам лучше использовать EnumMap для кэширования enum -> int отображение.

9 голосов
/ 04 мая 2011

Перечисления Java не имеют того же типа сопоставления перечисления с целым, что и в C ++.

При этом все перечисления имеют метод values, который возвращает массив возможных значений перечислениятак что

MyEnum enumValue = MyEnum.values()[x];

должно работать.Это немного неприятно, и, возможно, лучше не пытаться конвертировать из int с в Enum с (или наоборот), если это возможно.

7 голосов
/ 04 мая 2011

Использование MyEnum enumValue = MyEnum.values()[x];

6 голосов
/ 08 февраля 2015

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

public Enum MyEnum {
    THIS(5),
    THAT(16),
    THE_OTHER(35);

    private int id; // Could be other data type besides int
    private MyEnum(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }

    public static Map<Integer, MyEnum> buildMap() {
        Map<Integer, MyEnum> map = new HashMap<Integer, MyEnum>();
        MyEnum[] values = MyEnum.values();
        for (MyEnum value : values) {
            map.put(value.getId(), value);
        }

        return map;
    }
}

Мне нужно только преобразовать идентификаторы вперечисляет в определенное время (при загрузке данных из файла), поэтому у меня нет причин постоянно хранить карту в памяти.Если вам все время нужна карта, вы всегда можете кэшировать ее как статический член вашего класса Enum.

5 голосов
/ 16 ноября 2017

В случае, если это помогает другим, предпочтительный вариант, которого здесь нет в списке, использует Функциональность карт Гуавы :

public enum MyEnum {
    OPTION_1(-66),
    OPTION_2(32);

    private int value;
    private MyEnum(final int value) {
        this.value = value;
    }

    public int getValue() {
        return this.value;
    }

    private static ImmutableMap<Integer, MyEnum> reverseLookup = 
            Maps.uniqueIndex(Arrays.asList(MyEnum.values())), MyEnum::getValue);

    public static MyEnum fromInt(final int id) {
        return reverseLookup.getOrDefault(id, OPTION_1);
    }
}

По умолчанию вы можете использовать null,вы можете throw IllegalArgumentException или ваш fromInt может вернуть Optional, какое бы поведение вы ни выбрали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...