Cast Int to enum en Java


¿Cuál es la forma correcta de lanzar una Int a una enumeración en Java dada la siguiente enumeración?

public enum MyEnum
{
    EnumValue1,
    EnumValue2
}


MyEnum enumValue = (MyEnum) x; //Doesn't work???
Author: trumpetlicks, 2011-05-04

15 answers

Intenta MyEnum.values()[x] donde x debe ser 0 o 1, es decir, un ordinal válido para esa enumeración.

Tenga en cuenta que en Java las enumeraciones en realidad son clases (y los valores de enumeración, por lo tanto, son objetos) y, por lo tanto, no puede enviar un int o incluso Integer a una enumeración.

 527
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-21 13:57:33

MyEnum.values()[x] es una operación costosa. Si el rendimiento es una preocupación, es posible que desee hacer algo como esto:

public enum MyEnum {
    EnumValue1,
    EnumValue2;

    public static MyEnum fromInteger(int x) {
        switch(x) {
        case 0:
            return EnumValue1;
        case 1:
            return EnumValue2;
        }
        return null;
    }
}
 145
Author: Lorenzo Polidori,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-19 09:33:31

Si desea dar sus valores enteros, puede usar una estructura como la siguiente

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;
        }
}
 42
Author: Doctor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-08 14:36:02

Puedes probar así.
Crear clase con id de elemento.

      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;
            }
      }

Ahora obtiene esta enumeración usando id como int.

MyEnum myEnum = MyEnum.fromId(5);
 23
Author: Piyush Ghediya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-14 07:31:19

Caché los valores y crear un método de acceso estático simple:

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];
    }
}
 19
Author: ossys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-18 21:31:53

Las enumeraciones de Java no tienen el mismo tipo de mapeo enumeración a int que en C++.

Dicho esto, todas las enumeraciones tienen un método values que devuelve una matriz de valores posibles de enumeración, por lo que

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

Debería funcionar. Es un poco desagradable y podría ser mejor no tratar de convertir de int s a Enum s (o viceversa) si es posible.

 9
Author: Cameron Skinner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-04 05:29:53

Esto no es algo que se hace normalmente, así que lo reconsideraría. Pero dicho esto, las operaciones fundamentales son: int > > enum usando EnumType.values () [intNum], y enum int> int usando enumInst.ordinal().

Sin embargo, dado que cualquier implementación de values() no tiene más remedio que darle una copia de la matriz (las matrices java nunca son de solo lectura), sería mejor usar un EnumMap para almacenar en caché la asignación enum int> int.

 9
Author: Dilum Ranatunga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-04 05:32:32

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

 8
Author: w.donahue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-04 09:58:06

Esta es la solución con la que planeo ir. Esto no solo funciona con enteros no secuenciales, sino que debería funcionar con cualquier otro tipo de datos que desee usar como id subyacente para sus valores de enumeración.

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;
    }
}

Solo necesito convertir id's a enumeraciones en momentos específicos (al cargar datos de un archivo), por lo que no hay razón para mantener el Mapa en memoria en todo momento. Si necesita que el mapa sea accesible en todo momento, siempre puede almacenarlo en caché como un miembro estático de su enumeración clase.

 6
Author: jkindwall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-31 18:01:36

En caso de que ayude a otros, la opción que prefiero, que no aparece aquí, usa La funcionalidad de Mapas de Guayaba :

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);
    }
}

Con el valor predeterminado puede usar null, puede throw IllegalArgumentException o su fromInt podría devolver un Optional, cualquier comportamiento que prefiera.

 4
Author: Chad Befus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-16 01:13:19

Puede iterar sobre values() de enum y comparar el valor entero de enum con id dado como abajo:

public enum  TestEnum {
    None(0),
    Value1(1),
    Value2(2),
    Value3(3),
    Value4(4),
    Value5(5);

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

    public int getValue() {
        return value;
    }

    public static TestEnum  getEnum(int value){
        for (TestEnum e:TestEnum.values()) {
            if(e.getValue() == value)
                return e;
        }
        return TestEnum.None;//For values out of enum scope
    }
}

Y usar así:
TestEnum x = TestEnum.getEnum(4);//Will return TestEnum.Value4
Espero que esto ayude;)

 2
Author: Yashar Aliabasi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-19 16:45:17

Una buena opción es evitar la conversión de int a enum: por ejemplo, si necesita el valor máximo, puede comparar x.ordinal() con y.ordinal() y devolver x o y correspondientemente. (Es posible que tenga que volver a ordenar los valores para hacer que dicha comparación sea significativa.)

Si eso no es posible, almacenaría MyEnum.values() en una matriz estática.

 0
Author: 18446744073709551615,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-02 09:52:43

Esta es la misma respuesta que los doctores, pero muestra cómo eliminar el problema con arreglos mutables. Si usa este tipo de enfoque debido a la predicción de ramas primero, if tendrá muy poco efecto a cero y todo el código solo llama a la función mutable array values () solo una vez. Como ambas variables son estáticas no consumirán n * memoria para cada uso de esta enumeración también.

private static boolean arrayCreated = false;
private static RFMsgType[] ArrayOfValues;

public static RFMsgType GetMsgTypeFromValue(int MessageID) {
    if (arrayCreated == false) {
        ArrayOfValues = RFMsgType.values();
    }

    for (int i = 0; i < ArrayOfValues.length; i++) {
        if (ArrayOfValues[i].MessageIDValue == MessageID) {
            return ArrayOfValues[i];
        }
    }
    return RFMsgType.UNKNOWN;
}
 0
Author: Ali Akdurak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-22 18:55:16
enum MyEnum {
    A(0),
    B(1);
    private final int value;
    private MyEnum(int val) {this.value = value;}
    private static final MyEnum[] values = MyEnum.values();//cache for optimization
    public static final getMyEnum(int value) { 
        try {
            return values[value];//OOB might get triggered
        } catch (ArrayOutOfBoundsException e) {
        } finally {
            return myDefaultEnumValue;
        }
    }
}
 0
Author: Zoso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-14 23:10:59

Esto debería abordar los índices que no están sincronizados con el problema del valor ordinal.

package service.manager;

public enum Command {
    PRINT_FOO(0),
    PRINT_BAR(2),
    PRINT_BAZ(3);

    public int intVal;
    Command(int intVal){
        this.intVal = intVal;
    }

    /**
     * Functionality to ascertain an enum from an int
     * The static block initializes the array indexes to correspond with it's according ordinal value
     * Simply use Command.values[index] or get the int value by e.g. Command.PRINT_FOO.intVal;
     * */
    public static Command values[];
    static{
        int maxVal = -1;
        for(Command cmd : Command.values())
            if(maxVal < cmd.intVal)
                maxVal = cmd.intVal;

        values = new Command[maxVal + 1];

        for(Command cmd : Command.values())
            values[cmd.intVal] = cmd;
    }
}
 0
Author: Gerrit Brink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-06 17:18:11