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

And*_*oid 11 java enums enumeration casting

如何在Java中将值从Enum1转换为Enum 2?这是我正在尝试做的一个例子:

public enum Enum1 {
  ONE,
  TWO,
  THREE;
}

public enum Enum2 {
  FOUR,
  FIVE,
  SIX;
}
Run Code Online (Sandbox Code Playgroud)

所以我想做这样的事情:

Enum2 en2 = (Enum2)ONE;
Run Code Online (Sandbox Code Playgroud)

有可能,我该怎么做?

提前致谢!

Mic*_*jer 19

您不能从一个枚举转换为另一个枚举,但每个枚举都有保证顺序,您可以轻松地将一个枚举转换为另一个枚举(保留顺序).例如:

enum E1 {
    ONE, TWO, THREE,
}

enum E2 {
    ALPHA, BETA, GAMMA,
}
Run Code Online (Sandbox Code Playgroud)

我们可以翻译E1.TWO成/来自E2.BETA:

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

static E1 E2toE1(E2 value) {
    return E1.values()[value.ordinal()];
}
Run Code Online (Sandbox Code Playgroud)


Hei*_*bug 7

这是不可能的.Enum1和Enum2是不同的类型,没有任何共同之处.

  • +1:Java中的枚举不像C或C#中的枚举.它们没有一些常数数值的支持.它们实际上是完整的对象,带有一些特殊的编译器技巧,可以让它们在交换机等情况下工作.但即使它像C一样,我也会认为从一种"枚举"类型到另一种类型的直接转换,根据它们从编程角度来看它们应该代表什么,我认为这是一个糟糕的设计. (3认同)

use*_*421 6

您可以在Enum1中定义一个方法以返回相应的Enum2:

enum Enum1 {
    ONE {
        @Override
        public Enum2 toEnum2() {
            return Enum2.ALFA;
        }
    },
    TWO {
        @Override
        public Enum2 toEnum2() {
            return Enum2.BETA;
        }
    }
    ,
    THREE {
        @Override
        public Enum2 toEnum2() {
            return Enum2.GAMMA;
        }
    }
    ;

    public abstract Enum2 toEnum2();
}

enum Enum2 {
    ALFA, BETA, GAMMA;
}
Run Code Online (Sandbox Code Playgroud)

或者,更具可读性(IMO):

enum Enum1 {
    ONE(Enum2.ALFA), 
    TWO(Enum2.BETA), 
    THREE(Enum2.GAMMA);

    private final Enum2 enum2;

    private Enum1(Enum2 enum2) {
        this.enum2 = enum2;
    }

    public Enum2 toEnum2() {
        return enum2;
    }
}

enum Enum2 {
    ALFA, BETA, GAMMA;
}
Run Code Online (Sandbox Code Playgroud)

编辑:
如果您需要维护解耦的2个枚举,请创建一个包含从Enum1到Enum2(在第3个实用程序类中)的映射的映射.


cod*_*ing 6

尽管这张票很久以前就处于活动状态,我还是添加了另一种可能性:

您还可以创建一个地图,例如:

HashMap<Enum1, Enum2> e1ToE2 = new HashMap<Enum1, Enum2>();
e1ToE2.put(Enum1.ONE, Enum2.FOUR);
e1ToE2.put(Enum1.TWO, Enum2.FIVE);
Run Code Online (Sandbox Code Playgroud)

用法

Enum2 e2 = e1ToE2.get(Enum1.ONE);
Run Code Online (Sandbox Code Playgroud)

(+) 您不必仔细检查元素的顺序

(+) 易于阅读

(+) 快

(-) 需要空间

如我错了请纠正我 :)


Ste*_*ers 5

这个问题的答案可能取决于“广播”的预期作用:

按顺序铸造

在所提供的示例中,两个Enum中的值集之间没有共性,因此我假设要按顺序位置进行翻译,例如Enum1.ONE=> Enum2.FOUREnum1.TWO=> Enum2.FIVEEnum1.THREE=> Enum2.SIX。可以按照以下步骤进行:

Enum2 en2 = Enum2.values()[Enum1.ONE.ordinal()];
Run Code Online (Sandbox Code Playgroud)

下一个自然的问题是如何将其扩展为对任何两种enum类型都将执行相同操作的泛型函数。不是为胆小者准备的,但是以下方法可以完成工作(需要番石榴):

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

如果不存在Google Guava库,则可以通过以下几行代码手动完成:

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;
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

Enum2 en2 = castByOrdinal(Enum1.ONE, Enum2.class);
Run Code Online (Sandbox Code Playgroud)

通过共享枚举值名称进行转换

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

例如:

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

enum Size {
    SMALL, MEDIUM, LARGE, UNKNOWN, NOT_APPLICABLE
}
Run Code Online (Sandbox Code Playgroud)

此转换仅适用于通用值(即UNKNOWNNOT_APPLICABLE更高),并且可以按以下步骤进行:

Size size = Size.valueOf(Shape.UNKNOWN.name());
Run Code Online (Sandbox Code Playgroud)

如果目标枚举中不存在值名称,则将抛出IllegalArgumentException。这次,通用方法可能会更简单:

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

用法示例:

Size size = castByName(Shape.UNKNOWN, Size.class);
Run Code Online (Sandbox Code Playgroud)

  • 欣赏细节。 (2认同)