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

发布于 2024-12-03 04:53:30 字数 271 浏览 2 评论 0原文

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

public enum Enum1 {
  ONE,
  TWO,
  THREE;
}

public enum Enum2 {
  FOUR,
  FIVE,
  SIX;
}

所以我想做这样的事情:

Enum2 en2 = (Enum2)ONE;

这可能吗?我该怎么做?

提前致谢!

How can I cast a value from Enum1 to Enum 2 in Java?
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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

窗影残 2024-12-10 04:53:30

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

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()];
}

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:

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

static E1 E2toE1(E2 value) {
    return E1.values()[value.ordinal()];
}
一身仙ぐ女味 2024-12-10 04:53:30

答案取决于“转换”应该做什么...

按序数位置转换

在提供的示例中,两组枚举值之间没有共性,因此我假设意图是按序数位置进行翻译 - 所以<代码>Enum1.ONE => Enum2.FOUR, Enum1.TWO => Enum2.FIVEEnum1.THREE => Enum2.SIX。这可以按照下面的示例来完成,该示例从 Enum1.ONE 进行转换(将 en2 分配给 Enum2.FOUR

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

:问题是如何将其扩展为对任意两种 enum 类型执行相同操作的通用函数。不适合胆小的人,但这可以完成工作 - 它需要 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
}

转换仅适用于常见值(即上面的 UNKNOWNNOT_APPLICABLE),并且可以按照下面的示例完成,该示例从 Shape.UNKNOWN 进行转换 (将 size 分配给 Size.UNKNOWN):

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

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. This can be done as per the example below, which casts from Enum1.ONE (assigning en2 to Enum2.FOUR):

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

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:

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

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. UNKNOWN and NOT_APPLICABLE above) and can be done as per the example below, which casts from Shape.UNKNOWN (assigning size to Size.UNKNOWN):

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

This will throw an IllegalArgumentException if the value name does not exist in the target enum. 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);
春夜浅 2024-12-10 04:53:30

您可以在 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;
}

或者,更具可读性(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;
}

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

You can define a method in Enum1 to return the corresponding 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):

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

无法言说的痛 2024-12-10 04:53:30

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

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

难得心□动 2024-12-10 04:53:30

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

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

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

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

(+)易于阅读

(+ ) 快速

(-) 需要空间

如果我错了请纠正我:)

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

我们只是彼此的过ke 2024-12-10 04:53:30

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

您可以根据序数值或名称从一种转换为另一种,但我对任何需要执行此操作的程序的设计提出质疑。

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.

嘿哥们儿 2024-12-10 04:53:30

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

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.

大姐,你呐 2024-12-10 04:53:30

强制转换操作是不可能的,但您可以为 enum1 编写一个静态成员函数,将 enum2 强制转换为 enum1:

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

顺便说一句,您可以为两个枚举的每个常量分配一个 ID,从而简化实现。

这里是关于枚举的教程。

A cast operation is not possible, but you can write a static member function for enum1 that casts enum2 to 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.

Here is a tutorial on enums.

泡沫很甜 2024-12-10 04:53:30

它可能不会帮助您,但您可以拥有

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

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

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.

感性 2024-12-10 04:53:30

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

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

月棠 2024-12-10 04:53:30

如果您需要默认值:

Arrays.stream(Enum2.values())
      .filter(value -> value.name().equals(Enum1.ONE.name()))
      .findFirst()
      .orElse(Enum2.FOUR)

If you need a default value:

Arrays.stream(Enum2.values())
      .filter(value -> value.name().equals(Enum1.ONE.name()))
      .findFirst()
      .orElse(Enum2.FOUR)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文