简体   繁体   English

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

[英]How to cast a value from one enum to another in Java?

How can I cast a value from Enum1 to Enum 2 in Java?如何在 Java 中将值从 Enum1 转换为 Enum 2? Here is an example of what I'm trying to do:这是我正在尝试做的一个例子:

public enum Enum1 {
  ONE,
  TWO,
  THREE;
}

public enum Enum2 {
  FOUR,
  FIVE,
  SIX;
}

So I want to do something like this:所以我想做这样的事情:

Enum2 en2 = (Enum2)ONE;

Is it possible and how can I do that?有可能吗?我该怎么做?

Thanks in advance!提前致谢!

You cannot cast from one enum to another, however each enum has guaranteed order, and you can easily translate one enum to another (preserving order).您不能从一个枚举转换到另一个枚举,但是每个枚举都有保证的顺序,并且您可以轻松地将一个枚举转换为另一个(保留顺序)。 For example:例如:

enum E1 {
    ONE, TWO, THREE,
}

enum E2 {
    ALPHA, BETA, GAMMA,
}

we can translate E1.TWO to/from E2.BETA by:我们可以通过以下方式将E1.TWO翻译成/从E2.BETA

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

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

The answer depends on what the "casting" should do...答案取决于“铸造”应该做什么......

Casting by ordinal position按顺序铸造

In the provided example, there is no commonality between the two sets of enum values so I'm assuming the intention was to translate by ordinal position so Enum1.ONE => Enum2.FOUR , Enum1.TWO => Enum2.FIVE and Enum1.THREE => Enum2.SIX .在提供的示例中,两组枚举值之间没有共性,因此我假设目的是按顺序位置进行转换,因此Enum1.ONE => Enum2.FOUREnum1.TWO => Enum2.FIVEEnum1.THREE => Enum2.SIX This can be done as follows:这可以按如下方式完成:

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

A natural follow-on question is how this can be extended to a generic function that does the same for any two enum types.一个自然的后续问题是如何将其扩展到对任何两种enum类型执行相同操作的泛型函数。 Not for the faint hearted but this does the job - it requires the Google Guava library:不适合胆小的人,但这可以完成工作 - 它需要 Google Guava 库:

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

If Guava isn't being used, it can be done manually in a few more lines of code:如果没有使用 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;
}

Example usage:用法示例:

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

Casting by shared enum value names通过共享枚举值名称进行转换

There is another possible way of casting between enums that share some of the same value names.还有另一种在共享一些相同值名称的枚举之间进行转换的可能方法。

Eg:例如:

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

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

The casting will only work for common values (ie UNKNOWN and NOT_APPLICABLE above) and can be done as follows:转换仅适用于常见值(即上面的UNKNOWNNOT_APPLICABLE ),并且可以按如下方式完成:

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

This will throw an IllegalArgumentException if the value name does not exist in the target enum.如果目标枚举中不存在值名称,这将引发IllegalArgumentException The generic method for this casting is a bit simpler:这个转换的通用方法稍微简单一点:

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

Example usage:用法示例:

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

You can define a method in Enum1 to return the corresponding Enum2:可以在 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;
}

or, a bit more readable (IMO):或者,更具可读性(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;
}

EDIT:编辑:
if you need to maintain the 2 enums decoupled, create a map containing the mapping from Enum1 to Enum2 (in a 3rd utility class).如果您需要保持 2 个枚举解耦,请创建一个映射,其中包含从 Enum1 到 Enum2 的映射(在第三个实用程序类中)。

It's not possible.这是不可能的。 Enum1 and Enum2 are different types with nothing in common. Enum1 和 Enum2 是不同的类型,没有任何共同之处。

You can't do that, because they're objects of different classes.你不能这样做,因为它们是不同类的对象。

You could convert from one to the other based on ordinal value or name, but I'd question the design of any program that needed to do that.您可以根据序号值或名称从一个转换为另一个,但我怀疑任何需要这样做的程序的设计。

Even though this ticket was active quite a while ago I'm adding another possibility:尽管这张票在很久以前就处于活跃状态,我还是要添加另一种可能性:

You could also create a Map eg like this:你也可以像这样创建一个地图:

HashMap<Enum1, Enum2> e1ToE2 = new HashMap<Enum1, Enum2>();
e1ToE2.put(Enum1.ONE, Enum2.FOUR);
e1ToE2.put(Enum1.TWO, Enum2.FIVE);

usage用法

Enum2 e2 = e1ToE2.get(Enum1.ONE);

(+) you dont have to double check the order of your elements (+) 您不必仔细检查元素的顺序

(+) easy to read (+) 易于阅读

(+) fast (+) 快

(-) requires space (-) 需要空间

Correct me if I'm wrong :)如果我错了纠正我 :)

You can't ;你不能; but you can create a static method in your enums, with a translation code.但是您可以在枚举中创建一个静态方法,并带有翻译代码。 But you must have a clear idea of the rules you want to implement.但是您必须清楚地了解要实施的规则。

A cast operation is not possible, but you can write a static member function for enum1 that casts enum2 to enum1:转换操作是不可能的,但您可以为 enum1 编写一个静态成员函数,将 enum2 转换为 enum1:

public static Enum1 fromEnum2(Enum2 enum2) {
    ...
}

By the way, you can assign an ID to every constant of both enums which simplifies the implementation.顺便说一下,您可以为两个枚举的每个常量分配一个 ID,这简化了实现。

Here is a tutorial on enums. 是一个关于枚举的教程。

您不能从一个枚举转换到另一个枚举,但是每个枚举都有保证的顺序,并且您可以轻松地将一个枚举转换为另一个

It probably won't help you, but you can have它可能不会帮助你,但你可以

public enum Enum1 implements MyInterface {...}
public enum Enum2 implements MyInterface {...}

We don't have enough information about what you are trying to do to help you.我们没有足够的信息来说明您正在尝试做些什么来帮助您。 It makes no sense as it is to cast an enum to another enum.将一个枚举转换为另一个枚举是没有意义的。

You can do this by using simple way:您可以使用简单的方法来做到这一点:

 public enum number{one,two};
        public enum number1{one,two};
        public void  castTonumber1(number number){

            number1 num1 = number1.valueOf(number.one.toString());
           System.out.println( "value of number 1 is " + num1);

        }*

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM