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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7284472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 19:24:47  来源:igfitidea点击:

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

javaenumscastingenumeration

提问by Android-Droid

How can I cast a value from Enum1 to Enum 2 in Java? Here is an example of what I'm trying to do :

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

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!

提前致谢!

回答by Micha? ?rajer

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.TWOto/from E2.BETAby:

我们可以翻译E1.TWO从到/E2.BETA由:

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

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

回答by Steve Chambers

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.FIVEand Enum1.THREE=> Enum2.SIX. This can be done as follows:

在提供的示例中,两组枚举值之间没有共性,因此我假设目的是按序数位置进行转换,因此Enum1.ONE=> Enum2.FOUREnum1.TWO=>Enum2.FIVEEnum1.THREE=> Enum2.SIX。这可以按如下方式完成:

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 enumtypes. Not for the faint hearted but this does the job - it requires the Google Guava library:

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

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

If the 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.

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

E.g:

例如:

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 (i.e. UNKNOWNand NOT_APPLICABLEabove) and can be done as follows:

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

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

This will throw an IllegalArgumentExceptionif the value name does not exist in the target enum. The generic method for this casting is a bit simpler:

IllegalArgumentException如果目标枚举中不存在值名称,这将抛出一个。这个转换的通用方法稍微简单一点:

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);

回答by user85421

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 的映射(在第三个实用程序类中)。

回答by Heisenbug

It's not possible. Enum1 and Enum2 are different types with nothing in common.

这是不可能的。Enum1 和 Enum2 是不同的类型,没有任何共同点。

回答by parsifal

You can't do that, because they're objects of different classes.

你不能这样做,因为它们是不同类的对象。

You could convertfrom one to the other based on ordinal value or name, but I'd question the design of any program that needed to do that.

您可以根据序号值或名称从一个转换为另一个,但我怀疑任何需要这样做的程序的设计。

回答by Raveline

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.

你不能;但是您可以在枚举中创建一个静态方法,并带有翻译代码。但是您必须清楚地了解要实施的规则。

回答by codewing

Even though this ticket was active quite a while ago I'm adding another possibility:

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

You could also create a Map e.g. 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 :)

如我错了请纠正我 :)

回答by alfa

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,这简化了实现。

Hereis a tutorial on enums.

是一个关于枚举的教程。

回答by toto2

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.

我们没有足够的信息来说明您正在尝试做些什么来帮助您。将一个枚举转换为另一个枚举是没有意义的。

回答by T.Harini

You cannot cast from one enum to another, however each enum has guaranteed order, and you can easily translate one enum to another

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