在Java中将Int转换为枚举类型

386
在Java中,将Int转换为枚举的正确方法是什么?给定以下枚举要怎么做?
public enum MyEnum
{
    EnumValue1,
    EnumValue2
}


MyEnum enumValue = (MyEnum) x; //Doesn't work???
17个回答

6

根据@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());
    }
}

这能在double、short、float、long上运行吗? - deepakl.2000
@deepakl.2000 :枚举值是整数值,所以仅支持int是有效的。我认为不可能有一个具有浮点序数的枚举。 - Mark Douglas
@deepakl.2000 :枚举值是整数值,因此仅支持int是有效的。我认为不可能有一个枚举具有浮点序数的例子。 - undefined

4
您可以遍历枚举的 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);//将返回TestEnum.Value4
希望这能帮到你;)


3
我写了这个实现。它允许缺失值、负值,并保持代码的一致性。该映射也被缓存了。需要使用接口和Java 8。
枚举(Enum)
public enum Command implements OrdinalEnum{
    PRINT_FOO(-7),
    PRINT_BAR(6),
    PRINT_BAZ(4);

    private int val;
    private Command(int val){
        this.val = val;
    }

    public int getVal(){
        return val;
    }

    private static Map<Integer, Command> map = OrdinalEnum.getValues(Command.class);
    public static Command from(int i){
        return map.get(i);
    }
}

接口

public interface OrdinalEnum{
    public int getVal();

    @SuppressWarnings("unchecked")
    static <E extends Enum<E>> Map<Integer, E> getValues(Class<E> clzz){
        Map<Integer, E> m = new HashMap<>();
        for(Enum<E> e : EnumSet.allOf(clzz))
            m.put(((OrdinalEnum)e).getVal(), (E)e);

        return m;
    }
}

评论 :: 你能否写一些代码注释,以便开发人员能够理解逐步的逻辑? - deepakl.2000

1
在Kotlin中:
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)!!

0
一个不错的选择是避免int转换为enum:例如,如果你需要最大值,可以比较x.ordinal()和y.ordinal(),然后相应地返回x或y。(你可能需要重新排列你的值以使这种比较有意义。)

如果不可能,我会将MyEnum.values()存储在静态数组中。


2
如果您从数据库中获取int并想将其转换为Enum,我认为这是一个非常常见的任务,您需要进行int->枚举类型的转换。 - Yuki Inoue

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

不要在边界检查的位置使用异常。 - shmosel
@shmosel 我认为如果越界的情况相对较少,异常处理会更好。 - Zoso
你的信仰基于什么? - shmosel

0

这与医生的答案相同,但它展示了如何消除可变数组的问题。如果您使用这种方法是因为分支预测,那么第一个if将几乎没有任何影响,并且整个代码仅调用可变数组values()函数一次。由于两个变量都是静态的,它们在每次使用此枚举时也不会消耗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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接