recorrer que enum java casting enums ordinal

recorrer - que es un enum en java



Cast Int para enum en Java (15)

Aquí está la solución con la que planeo ir. Esto no solo funciona con enteros no secuenciales, sino que también debería funcionar con cualquier otro tipo de datos que desee utilizar como la identificación 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 los identificadores en enumerados en momentos específicos (al cargar datos de un archivo), por lo que no tengo ninguna razón para mantener el mapa en la memoria en todo momento. Si necesita que el mapa sea accesible en todo momento, siempre puede guardarlo como miembro estático de su clase Enum.

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

public enum MyEnum { EnumValue1, EnumValue2 } MyEnum enumValue = (MyEnum) x; //Doesn''t work???


En caso de que ayude a otros, la opción que prefiero, que no aparece en esta lista, usa la funcionalidad de Mapas de Guava :

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 , cualquiera que sea el comportamiento que prefiera.


Esta es la misma respuesta que los médicos, pero muestra cómo eliminar el problema con arreglos mutables. Si utiliza este tipo de enfoque debido a la predicción de ramificación primero, tendrá un efecto de muy poco a cero y el código completo solo llamará a la función de valores de matriz mutable () solo una vez. Como ambas variables son estáticas, tampoco consumirán n * memoria por cada uso de esta enumeració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; }


Esto debería hacer que los índices 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; } }


Esto no es algo que normalmente se hace, así que lo reconsideraría. Pero dicho esto, las operaciones fundamentales son: int -> enum utilizando EnumType.values ​​() [intNum], y enum -> 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 utilizar un EnumMap para almacenar en caché la asignación enum -> int.


Guardo los valores y creo un método simple de acceso estático:

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


Las enumeraciones de Java no tienen el mismo tipo de asignación enum-to-int que tienen en C ++.

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

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

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


Pruebe 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 las enumeraciones de Java en realidad son clases (y los valores de enumeración son objetos) y, por lo tanto, no puede convertir un int o incluso un Integer en una enumeración.


Puede iterar sobre los values() de la enumeración y comparar el valor entero de la enumeración con el id dado como se muestra a continuación:

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í como esto:
TestEnum x = TestEnum.getEnum(4);//Will return TestEnum.Value4
Espero que esto ayude ;)


Puedes intentarlo así.
Crear clase con el elemento id.

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 trae este Enum usando id como int.

MyEnum myEnum = MyEnum.fromId(5);


Si desea dar valores enteros, puede usar una estructura como la que se muestra a continuación

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


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 de manera correspondiente. (Es posible que deba reordenar sus valores para que dicha comparación sea significativa).

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


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


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


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