在给定以下枚举的情况下,将Int转换为枚举的正确方法是什么?
public enum MyEnum
{
EnumValue1,
EnumValue2
}
MyEnum enumValue = (MyEnum) x; //Doesn't work???
答案 0 :(得分:550)
尝试MyEnum.values()[x]
,其中x
必须是0
或1
,即该枚举的有效序号。
请注意,在Java枚举中实际上是类(并且枚举值因此是对象),因此您无法将int
甚至Integer
强制转换为枚举。
答案 1 :(得分:151)
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;
}
}
答案 2 :(得分:43)
如果要提供整数值,可以使用如下结构
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;
}
}
答案 3 :(得分:26)
你可以这样试试。
使用元素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;
}
}
现在使用id作为int获取此枚举。
MyEnum myEnum = MyEnum.fromId(5);
答案 4 :(得分:19)
我缓存这些值并创建一个简单的静态访问方法:
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];
}
}
答案 5 :(得分:9)
Java枚举与C ++中的enum-to-int映射不同。
也就是说,所有枚举都有一个values
方法,它返回一个可能的枚举值数组,所以
MyEnum enumValue = MyEnum.values()[x];
应该有效。这有点令人讨厌,如果可能的话,最好不要尝试从int
转换为Enum
s(反之亦然)。
答案 6 :(得分:9)
这不是通常会做的事情,所以我会重新考虑。但话说回来,基本操作是:int - &gt; enum使用EnumType.values()[intNum]和enum - &gt; int使用enumInst.ordinal()。
但是,由于values()的任何实现别无选择,只能给你一个数组的副本(java数组永远不会是只读的),你可以使用EnumMap缓存枚举 - > gt; int mapping。
答案 7 :(得分:7)
使用MyEnum enumValue = MyEnum.values()[x];
答案 8 :(得分:6)
这是我计划采用的解决方案。这不仅适用于非顺序整数,而且它可以与您可能希望用作枚举值的基础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 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转换为枚举(从文件加载数据时),因此我没有理由始终将Map保留在内存中。如果您确实需要始终可以访问地图,您可以随时将其缓存为Enum类的静态成员。
答案 9 :(得分:5)
如果它对其他人有帮助,我更喜欢的选项(此处未列出)使用Guava's Maps functionality:
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
,无论您喜欢什么行为。
答案 10 :(得分:2)
您可以迭代枚举的values()
,并将枚举的整数值与给定的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
我希望这会有所帮助;)
答案 11 :(得分:1)
基于@ChadBefus的答案和@shmosel注释,我建议您使用它。 (高效查找,并且可以在纯Java> = 8上运行)
import java.util.stream.Collectors;
import java.util.function.Function;
import java.util.Map;
import java.util.Arrays;
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 Map<Integer, MyEnum> reverseLookup =
Arrays.stream(MyEnum.values()).collect(Collectors.toMap(MyEnum::getValue, Function.identity()));
public static MyEnum fromInt(final int id) {
return reverseLookup.getOrDefault(id, OPTION_1);
}
public static void main(String[] args) {
System.out.println(fromInt(-66).toString());
}
}
答案 12 :(得分:0)
在科特林:
enum class Status(val id: Int) {
NEW(0), VISIT(1), IN_WORK(2), FINISHED(3), CANCELLED(4), DUMMY(5);
companion object {
private val statuses = Status.values().associateBy(Status::id)
fun getStatus(id: Int): Status? = statuses[id]
}
}
用法:
val status = Status.getStatus(1)!!
答案 13 :(得分:0)
这应解决索引与序数值问题不同步的问题。
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;
}
}
答案 14 :(得分:0)
error
答案 15 :(得分:0)
这与医生的答案相同,但它显示了如何消除可变阵列的问题。如果你使用这种方法,因为分支预测首先是否会产生非常小的效果,整个代码只调用一次可变数组值()函数。由于这两个变量都是静态的,因此每次使用此枚举时也不会消耗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;
}
答案 16 :(得分:0)
一个好的选择是避免从int
转换为enum
:例如,如果您需要最大值,您可以将x.ordinal()与y进行比较.ordinal()并相应地返回x或y。 (您可能需要重新排序值以使这种比较有意义。)
如果无法做到这一点,我会将MyEnum.values()
存储到静态数组中。