我该如何在Java中将Enum1的值转换为Enum2?以下是我正在尝试的示例:
public enum Enum1 {
ONE,
TWO,
THREE;
}
public enum Enum2 {
FOUR,
FIVE,
SIX;
}
所以我想做这样的事情:
Enum2 en2 = (Enum2)ONE;
这是否可能,如果可能的话,我应该如何做呢?
先行致谢!
我该如何在Java中将Enum1的值转换为Enum2?以下是我正在尝试的示例:
public enum Enum1 {
ONE,
TWO,
THREE;
}
public enum Enum2 {
FOUR,
FIVE,
SIX;
}
所以我想做这样的事情:
Enum2 en2 = (Enum2)ONE;
这是否可能,如果可能的话,我应该如何做呢?
先行致谢!
你不能从一个枚举类型直接转换为另一个枚举类型,不过每个枚举类型都有保证的顺序,并且可以轻松地将一个枚举类型翻译成另一个枚举类型(保留顺序)。例如:
enum E1 {
ONE, TWO, THREE,
}
enum E2 {
ALPHA, BETA, GAMMA,
}
我们可以通过以下方式将E1.TWO
翻译为/从E2.BETA
:
static E2 E1toE2(E1 value) {
return E2.values()[value.ordinal()];
}
static E1 E2toE1(E2 value) {
return E1.values()[value.ordinal()];
}
答案取决于"casting"应该做什么......
在提供的示例中,两组枚举值之间没有共同点,因此我假设意图是按序数位置进行转换,所以 Enum1.ONE
=> Enum2.FOUR
,Enum1.TWO
=> Enum2.FIVE
,Enum1.THREE
=> Enum2.SIX
。可按以下方式完成:
Enum2 en2 = Enum2.values()[Enum1.ONE.ordinal()];
枚举
类型执行相同的操作。这不是一件容易的事情,但可以使用Google Guava库完成。public <F extends Enum<F>> F castByOrdinal(Enum<?> e, Class<F> fClass) {
return Iterators.get(EnumSet.allOf(fClass).iterator(), e.ordinal());
}
如果没有使用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 an exception 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
}
强制转换只适用于常见值(即上面的UNKNOWN
和NOT_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);
您可以在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;
}
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;
}
编辑:
如果需要保持两个枚举类解耦,可以创建一个包含从Enum1到Enum2的映射的Map(在第三个实用程序类中)。
不可能的。Enum1和Enum2是两种没有任何共同点的不同类型。
虽然这个票已经很久之前就激活了,但我还要添加另一种可能性:
您也可以创建一个地图,例如像这样:
HashMap<Enum1, Enum2> e1ToE2 = new HashMap<Enum1, Enum2>();
e1ToE2.put(Enum1.ONE, Enum2.FOUR);
e1ToE2.put(Enum1.TWO, Enum2.FIVE);
使用方法
Enum2 e2 = e1ToE2.get(Enum1.ONE);
(+) 无需再次检查您的元素顺序
(+) 易于阅读
(+) 快速
(-) 需要空间
如果我有错误,请纠正我 :)
由于它们是不同类的对象,所以您无法这样做。
您可以基于序数值或名称进行转换,但我会质疑任何需要执行此操作的程序的设计。
enum Enum1 { ONE { public Enum2 toEnum2() { return Enum2.FOUR; } },...
你还应该为整个枚举类型添加一个抽象方法。 - user85421public static Enum1 fromEnum2(Enum2 enum2) {
...
}
它可能对你没有帮助,但你可以拥有
public enum Enum1 implements MyInterface {...}
public enum Enum2 implements MyInterface {...}
你不能将一个枚举类型转换为另一个枚举类型,但是每个枚举类型都有保证的顺序,因此你可以轻松地将一个枚举类型翻译成另一个枚举类型
Enum1.ONE
进行“强制转换”为en2
时,你期望en2
保持什么值? - Joachim Sauer