从枚举序号转换为枚举类型

落日映苍穹つ 2023-03-05 03:23 84阅读 0赞

本文翻译自:Convert from enum ordinal to enum type

I’ve the enum type ReportTypeEnum that get passed between methods in all my classes but I then need to pass this on the URL so I use the ordinal method to get the int value. 我在我的所有类中的方法之间传递了枚举类型ReportTypeEnum ,但是我需要在URL上传递它,所以我使用序数方法来获取int值。 After I get it in my other JSP page, I need to convert it to back to an ReportTypeEnum so that I can continue passing it. 在我的其他JSP页面中获取它之后,我需要将其转换回ReportTypeEnum以便我可以继续传递它。

How can I convert ordinal to the ReportTypeEnum ? 如何将序数转换为ReportTypeEnum

Using Java 6 SE. 使用Java 6 SE。


#1楼

参考:https://stackoom.com/question/2yEs/从枚举序号转换为枚举类型


#2楼

Every enum has name(), which gives a string with the name of enum member. 每个枚举都有name(),它给出一个名为enum成员的字符串。

Given enum Suit{Heart, Spade, Club, Diamond} , Suit.Heart.name() will give Heart . 鉴于enum Suit{Heart, Spade, Club, Diamond}Suit.Heart.name()将给予Heart

Every enum has a valueOf() method, which takes an enum type and a string, to perform the reverse operation: 每个枚举都有一个valueOf()方法,它采用枚举类型和字符串来执行反向操作:

Enum.valueOf(Suit.class, "Heart") returns Suit.Heart . Enum.valueOf(Suit.class, "Heart")返回Suit.Heart

Why anyone would use ordinals is beyond me. 为什么有人会使用序数超出我的范围。 It may be nanoseconds faster, but it is not safe, if the enum members change, as another developer may not be aware some code is relying on ordinal values (especially in the JSP page cited in the question, network and database overhead completely dominates the time, not using an integer over a string). 它可能要快几纳秒,但是如果枚举成员发生变化则不安全,因为另一个开发人员可能不知道某些代码依赖于序数值(特别是在问题中引用的JSP页面中,网络和数据库开销完全占主导地位)时间,不使用字符串上的整数)。


#3楼

If I’m going to be using values() a lot: 如果我要使用values()很多:

  1. enum Suit {
  2. Hearts, Diamonds, Spades, Clubs;
  3. public static final Suit values[] = values();
  4. }

Meanwhile wherever.java: 同时wherever.java:

  1. Suit suit = Suit.values[ordinal];

Mind your array bounds. 注意阵列界限。


#4楼

I agree with most people that using ordinal is probably a bad idea. 我同意大多数人使用序数可能是一个坏主意。 I usually solve this problem by giving the enum a private constructor that can take for example a DB value then create a static fromDbValue function similar to the one in Jan’s answer. 我通常通过给枚举一个私有构造函数来解决这个问题,该构造函数可以采用例如DB值,然后创建一个类似于Jan答案中的静态fromDbValue函数。

  1. public enum ReportTypeEnum {
  2. R1(1),
  3. R2(2),
  4. R3(3),
  5. R4(4),
  6. R5(5),
  7. R6(6),
  8. R7(7),
  9. R8(8);
  10. private static Logger log = LoggerFactory.getLogger(ReportEnumType.class);
  11. private static Map<Integer, ReportTypeEnum> lookup;
  12. private Integer dbValue;
  13. private ReportTypeEnum(Integer dbValue) {
  14. this.dbValue = dbValue;
  15. }
  16. static {
  17. try {
  18. ReportTypeEnum[] vals = ReportTypeEnum.values();
  19. lookup = new HashMap<Integer, ReportTypeEnum>(vals.length);
  20. for (ReportTypeEnum rpt: vals)
  21. lookup.put(rpt.getDbValue(), rpt);
  22. }
  23. catch (Exception e) {
  24. // Careful, if any exception is thrown out of a static block, the class
  25. // won't be initialized
  26. log.error("Unexpected exception initializing " + ReportTypeEnum.class, e);
  27. }
  28. }
  29. public static ReportTypeEnum fromDbValue(Integer dbValue) {
  30. return lookup.get(dbValue);
  31. }
  32. public Integer getDbValue() {
  33. return this.dbValue;
  34. }
  35. }

Now you can change the order without changing the lookup and vice versa. 现在您可以在不更改查找的情况下更改顺序,反之亦然。


#5楼

This is what I use. 这就是我使用的。 I make no pretense that it’s far less “efficient” than the simpler solutions above. 我并没有假装它比上面简单的解决方案更“有效”。 What it does do is provide a much clearer exception message than “ArrayIndexOutOfBounds” when an invalid ordinal value is used in the solution above. 当在上面的解决方案中使用无效的序数值时,它所做的是提供比“ArrayIndexOutOfBounds”更清晰的异常消息。

It utilizes the fact that EnumSet javadoc specifies the iterator returns elements in their natural order. 它利用了EnumSet javadoc指定迭代器以其自然顺序返回元素的事实。 There’s an assert if that’s not correct. 如果这不正确,就会有一个断言。

The JUnit4 Test demonstrates how it’s used. JUnit4测试演示了它是如何使用的。

  1. /**
  2. * convert ordinal to Enum
  3. * @param clzz may not be null
  4. * @param ordinal
  5. * @return e with e.ordinal( ) == ordinal
  6. * @throws IllegalArgumentException if ordinal out of range
  7. */
  8. public static <E extends Enum<E> > E lookupEnum(Class<E> clzz, int ordinal) {
  9. EnumSet<E> set = EnumSet.allOf(clzz);
  10. if (ordinal < set.size()) {
  11. Iterator<E> iter = set.iterator();
  12. for (int i = 0; i < ordinal; i++) {
  13. iter.next();
  14. }
  15. E rval = iter.next();
  16. assert(rval.ordinal() == ordinal);
  17. return rval;
  18. }
  19. throw new IllegalArgumentException("Invalid value " + ordinal + " for " + clzz.getName( ) + ", must be < " + set.size());
  20. }
  21. @Test
  22. public void lookupTest( ) {
  23. java.util.concurrent.TimeUnit tu = lookupEnum(TimeUnit.class, 3);
  24. System.out.println(tu);
  25. }

#6楼

  1. public enum Suit implements java.io.Serializable, Comparable<Suit>{
  2. spades, hearts, diamonds, clubs;
  3. private static final Suit [] lookup = Suit.values();
  4. public Suit fromOrdinal(int ordinal) {
  5. if(ordinal< 1 || ordinal> 3) return null;
  6. return lookup[value-1];
  7. }
  8. }

the test class 考试班

  1. public class MainTest {
  2. public static void main(String[] args) {
  3. Suit d3 = Suit.diamonds;
  4. Suit d3Test = Suit.fromOrdinal(2);
  5. if(d3.equals(d3Test)){
  6. System.out.println("Susses");
  7. }else System.out.println("Fails");
  8. }
  9. }

I appreciate that you share with us if you have a more efficient code, My enum is huge and constantly called thousands of times. 如果你有更高效的代码,我很感激你与我们分享,我的枚举是巨大的,不断被召唤数千次。

发表评论

表情:
评论列表 (有 0 条评论,84人围观)

还没有评论,来说两句吧...

相关阅读

    相关 类型

    枚举类型的定义和枚举变量的说明  1.  枚举的定义枚举类型定义的一般形式为:      enum 枚举名\{ 枚举值表 \};  在枚举值表中应罗列出所有可用值。