如何在Java中将值从一个枚举转换为另一个枚举?

2022-09-02 05:01:53

如何在Java中将值从Enum1强制转换为Enum 2?以下是我正在尝试执行的操作的示例:

public enum Enum1 {
  ONE,
  TWO,
  THREE;
}

public enum Enum2 {
  FOUR,
  FIVE,
  SIX;
}

所以我想做这样的事情:

Enum2 en2 = (Enum2)ONE;

有可能吗,我该怎么做?

提前致谢!


答案 1

您不能从一个枚举强制转换到另一个枚举,但是每个枚举都有保证的顺序,并且您可以轻松地将一个枚举转换为另一个枚举(保留顺序)。例如:

enum E1 {
    ONE, TWO, THREE,
}

enum E2 {
    ALPHA, BETA, GAMMA,
}

我们可以通过以下方式翻译到/从:E1.TWOE2.BETA

static E2 E1toE2(E1 value) {
    return E2.values()[value.ordinal()];
}

static E1 E2toE1(E2 value) {
    return E1.values()[value.ordinal()];
}

答案 2

答案取决于“选角”应该做什么......

按序号位置铸造

在提供的示例中,两组枚举值之间没有共性,因此我假设意图按序号位置进行转换,因此 => , => 和 = > 。这可以按如下方式完成:Enum1.ONEEnum2.FOUREnum1.TWOEnum2.FIVEEnum1.THREEEnum2.SIX

Enum2 en2 = Enum2.values()[Enum1.ONE.ordinal()];

一个自然的后续问题是,如何将其扩展到对任何两种类型执行相同操作的泛型函数。不适合胆小的人,但这可以完成工作 - 它需要Google番石榴库:enum

public <F extends Enum<F>> F castByOrdinal(Enum<?> e, Class<F> fClass) {
    return Iterators.get(EnumSet.allOf(fClass).iterator(), e.ordinal());
}

如果没有使用番石榴,可以在几行代码中手动完成:

public <F extends Enum<F>> F castByOrdinal(final Enum<?> e, final Class<F> fClass) {
    final Iterator<F> iter = EnumSet.allOf(fClass).iterator();
    int count = 0;
    F fValue = null;
    while (count <= e.ordinal()) {
        if (!iter.hasNext()) {
            return null; // Or throw exception if preferred e.g. IndexOutOfBoundsException
        }
        fValue = iter.next();
        count++;
    }

    return fValue;
}

用法示例:

Enum2 en2 = castByOrdinal(Enum1.ONE, Enum2.class);

按共享枚举值名称强制转换

在共享一些相同值名称的枚举之间转换还有另一种可能的方法。

例如:

enum Shape {
    TRIANGLE, SQUARE, PENTAGON, HEXAGON, UNKNOWN, NOT_APPLICABLE
}

enum Size {
    SMALL, MEDIUM, LARGE, UNKNOWN, NOT_APPLICABLE
}

转换仅适用于共同值(即 和以上),可以按如下方式完成:UNKNOWNNOT_APPLICABLE

Size size = Size.valueOf(Shape.UNKNOWN.name());

如果目标枚举中不存在值名称,这将引发一个。此转换的通用方法更简单一些:IllegalArgumentException

public <F extends Enum<F>> F castByName(final Enum<?> e, final Class<F> fClass) {
    return F.valueOf(fClass, e.name());
}

用法示例:

Size size = castByName(Shape.UNKNOWN, Size.class);