Max*_*ich 317 java enums casting ordinal
在给定以下枚举的情况下,将Int转换为枚举的正确方法是什么?
public enum MyEnum
{
EnumValue1,
EnumValue2
}
MyEnum enumValue = (MyEnum) x; //Doesn't work???
Run Code Online (Sandbox Code Playgroud)
Tho*_*mas 565
尝试必须在MyEnum.values()[x]哪里或,即该枚举的有效序数.x01
请注意,在Java枚举中实际上是类(并且枚举值因此是对象),因此您无法转换int或甚Integer至转换为枚举.
Lor*_*ori 154
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Doc*_*tor 45
如果要提供整数值,可以使用如下结构
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Piy*_*iya 31
你可以这样试试.
使用元素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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在使用id作为int获取此枚举.
MyEnum myEnum = MyEnum.fromId(5);
Run Code Online (Sandbox Code Playgroud)
oss*_*sys 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];
}
}
Run Code Online (Sandbox Code Playgroud)
Java枚举不具有与它们在C++中执行的相同类型的枚举到int映射.
也就是说,所有枚举都有一个values方法返回一个可能的枚举值数组,所以
MyEnum enumValue = MyEnum.values()[x];
Run Code Online (Sandbox Code Playgroud)
应该管用.这有点令人讨厌,如果可能的话,最好不要尝试从ints 转换为Enums(反之亦然).
这不是通常做的事情,所以我会重新考虑.但话说回来,基本操作是:int - > enum使用EnumType.values()[intNum],枚举 - > int使用enumInst.ordinal().
但是,由于values()的任何实现别无选择,只能为您提供数组的副本(java数组永远不会是只读的),因此使用EnumMap缓存枚举 - > int映射会更好.
小智 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我只需要在特定时间将id转换为枚举(从文件加载数据时),因此我没有理由始终将Map保留在内存中.如果确实需要始终可以访问地图,则可以始终将其缓存为Enum类的静态成员.
如果它有助于其他人,我喜欢的选项(这里没有列出)使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
使用您可以使用的默认值null,您可以throw IllegalArgumentException或者您fromInt可以返回Optional,无论您喜欢什么行为.
根据@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());
}
}
Run Code Online (Sandbox Code Playgroud)