投射诠释枚举在Java中

在给定下列枚举的情况下,将Int转换为Java的枚举的正确方法是什么?

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

尝试MyEnum.values()[x]其中x必须是01 ,即该枚举的有效序号。

请注意,在Java枚举实际上是类(和枚举值,因此是对象),因此你不能投一个int甚至Integer到一个枚举。

MyEnum.values()[x]是一个昂贵的操作。 如果performance是一个问题,你可能想要做这样的事情:

 public enum MyEnum { EnumValue1, EnumValue2; public static MyEnum fromInteger(int x) { switch(x) { case 0: return EnumValue1; case 1: return EnumValue2; } return null; } } 

如果你想给你的整数值,你可以使用下面的结构

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

我caching值并创build一个简单的静态访问方法:

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

你可以试试这个
用元素ID创build类。

  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 : MyEnum.values()) { if (type.getId() == id) { return type; } } return null; } } 

现在使用id作为int来获取这个枚举。

 MyEnum myEnum = MyEnum.fromId(5); 

这不是通常做的事情,所以我会重新考虑。 但话虽如此,基本的操作是:int – >枚举使用EnumType.values()[intNum],和枚举 – > int使用enumInst.ordinal()。

然而,由于values()的任何实现别无select,只能给你一个数组副本(java数组永远不会只读),所以使用EnumMap来cachingenum – > int映射会更好。

Java枚举没有像在C ++中那样的enum-to-int映射。

也就是说,所有枚举都有一个values方法,返回一个可能的枚举值数组,所以

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

应该pipe用。 这有点讨厌,如果可能的话,最好不要尝试从int转换为Enum (反之亦然)。

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

这是我打算去的解决scheme。 这不仅适用于非顺序整数,而且适用于任何其他可能需要用作枚举值的底层ID的数据types。

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

我只需要在特定的时间(从一个文件中加载数据的时候)将id转换为enums,所以我没有任何理由让Map永远保存在内存中。 如果您确实需要地图始终可以访问,则可以将其caching为Enum类的静态成员。

你可以迭代enum的values() ,并将enum的整数值与给定的id比较如下:

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

就像这样使用:
TestEnum x = TestEnum.getEnum(4);//Will return TestEnum.Value4
我希望这有帮助 ;)

如果它帮助别人,我喜欢的选项,这里没有列出,使用番石榴的地图function :

 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 ,你喜欢的任何行为。

一个好的select是避免intenum转换:例如,如果您需要最大值,可以将x.ordinal()与y.ordinal()进行比较,然后相应地返回x或y。 (您可能需要重新排列您的值才能使此类比较有意义。)

如果这是不可能的,我会将MyEnum.values()存储到一个静态数组中。

这与医生的答案是一样的,但它显示了如何消除可变数组的问题。 如果你首先使用这种方法是因为分支预测,如果将有很小的零效应,整个代码只调用一次可变数组values()函数。 由于这两个variables都是静态的,因此对于枚举的每次使用都不会消耗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; } 
 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; } } } 

这应该解决索引与序数值问题不同步的问题。

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