我有枚举类型ReportTypeEnum,在我所有的类的方法之间传递,但我需要在URL上传递这个,所以我使用序数方法来获得int值。在我的另一个JSP页面中获得它之后,我需要将它转换回ReportTypeEnum,以便我可以继续传递它。

如何将序数转换为ReportTypeEnum?

使用Java 6 SE。


当前回答

这就是我用的。我并不是说它远不如上面那些简单的解决方案“有效”。当在上面的解决方案中使用无效序数值时,它所做的是提供比"ArrayIndexOutOfBounds"更清晰的异常消息。

它利用了EnumSet javadoc指定迭代器以自然顺序返回元素的事实。如果不正确,就有一个断言。

JUnit4测试演示了如何使用它。

 /**
 * convert ordinal to Enum
 * @param clzz may not be null
 * @param ordinal
 * @return e with e.ordinal( ) == ordinal
 * @throws IllegalArgumentException if ordinal out of range
 */
public static <E extends Enum<E> > E lookupEnum(Class<E> clzz, int ordinal) {
    EnumSet<E> set = EnumSet.allOf(clzz);
    if (ordinal < set.size()) {
        Iterator<E> iter = set.iterator();
        for (int i = 0; i < ordinal; i++) {
            iter.next();
        }
        E rval = iter.next();
        assert(rval.ordinal() == ordinal);
        return rval;
    }
    throw new IllegalArgumentException("Invalid value " + ordinal + " for " + clzz.getName( ) + ", must be < " + set.size());
}

@Test
public void lookupTest( ) {
    java.util.concurrent.TimeUnit tu = lookupEnum(TimeUnit.class, 3);
    System.out.println(tu);
}

其他回答

安全第一(使用Kotlin):

// Default to null
EnumName.values().getOrNull(ordinal)

// Default to a value
EnumName.values().getOrElse(ordinal) { EnumName.MyValue }

So one way is to doExampleEnum valueOfOrdinal = ExampleEnum.values()[ordinal]; which works and its easy, however, as mentioned before, ExampleEnum.values() returns a new cloned array for every call. That can be unnecessarily expensive. We can solve that by caching the array like so ExampleEnum[] values = values(). It is also "dangerous" to allow our cached array to be modified. Someone could write ExampleEnum.values[0] = ExampleEnum.type2; So I would make it private with an accessor method that does not do extra copying.

private enum ExampleEnum{
    type0, type1, type2, type3;
    private static final ExampleEnum[] values = values();
    public static ExampleEnum value(int ord) {
        return values[ord];
    }
}

您可以使用exampleenumeration .value(ordinal)来获取与ordinal关联的枚举值

如果我要大量使用values():

enum Suit {
   Hearts, Diamonds, Spades, Clubs;
   public static final Suit values[] = values();
}

同时wherever.java:

Suit suit = Suit.values[ordinal];

如果你想要数组是私有的,请自便:

private static final Suit values[] = values();
public static Suit get(int ordinal) { return values[ordinal]; }

...

Suit suit = Suit.get(ordinal);

注意数组的边界。

这就是我用的。我并不是说它远不如上面那些简单的解决方案“有效”。当在上面的解决方案中使用无效序数值时,它所做的是提供比"ArrayIndexOutOfBounds"更清晰的异常消息。

它利用了EnumSet javadoc指定迭代器以自然顺序返回元素的事实。如果不正确,就有一个断言。

JUnit4测试演示了如何使用它。

 /**
 * convert ordinal to Enum
 * @param clzz may not be null
 * @param ordinal
 * @return e with e.ordinal( ) == ordinal
 * @throws IllegalArgumentException if ordinal out of range
 */
public static <E extends Enum<E> > E lookupEnum(Class<E> clzz, int ordinal) {
    EnumSet<E> set = EnumSet.allOf(clzz);
    if (ordinal < set.size()) {
        Iterator<E> iter = set.iterator();
        for (int i = 0; i < ordinal; i++) {
            iter.next();
        }
        E rval = iter.next();
        assert(rval.ordinal() == ordinal);
        return rval;
    }
    throw new IllegalArgumentException("Invalid value " + ordinal + " for " + clzz.getName( ) + ", must be < " + set.size());
}

@Test
public void lookupTest( ) {
    java.util.concurrent.TimeUnit tu = lookupEnum(TimeUnit.class, 3);
    System.out.println(tu);
}

你可以使用静态查找表:

public enum Suit {
  spades, hearts, diamonds, clubs;

  private static final Map<Integer, Suit> lookup = new HashMap<Integer, Suit>();

  static {
    int ordinal = 0;
    for (Suit suit : EnumSet.allOf(Suit.class)) {
      lookup.put(ordinal, suit);
      ordinal+= 1;
    }
  }

  public Suit fromOrdinal(int ordinal) {
    return lookup.get(ordinal);
  }
}