我ReportTypeEnum在所有类中的方法之间传递的枚举类型,但我需要在URL上传递它,所以我使用序数方法来获取int值.在我的其他JSP页面中获取它之后,我需要将其转换回一个ReportTypeEnum以便我可以继续传递它.
我如何将序数转换为ReportTypeEnum?
使用Java 6 SE.
Joa*_*uer 590
要将序数转换为其枚举represantation,您可能希望这样做:
ReportTypeEnum value = ReportTypeEnum.values()[ordinal];
Run Code Online (Sandbox Code Playgroud)
请注意数组边界.
请注意,每次调用都会values()返回一个新克隆的数组,这可能会以负面的方式影响性能.如果要经常调用它,您可能希望缓存该数组.
编辑此答案以包括评论中给出的反馈
oxb*_*kes 136
这几乎肯定是一个坏主意.当然,如果序数是事实上持久化的(例如因为某人已经为URL添加了书签) - 这意味着您必须始终保留enum将来的顺序,这对于维护人员的编码可能并不明显.
为什么不编码enumusing myEnumValue.name()(和解码via ReportTypeEnum.valueOf(s))呢?
QED*_*QED 89
如果我要使用values()很多:
enum Suit {
Hearts, Diamonds, Spades, Clubs;
public static final Suit values[] = values();
}
Run Code Online (Sandbox Code Playgroud)
同时wherever.java:
Suit suit = Suit.values[ordinal];
Run Code Online (Sandbox Code Playgroud)
注意阵列界限.
我同意大多数人使用序数可能是一个坏主意.我通常通过给枚举一个私有构造函数来解决这个问题,该构造函数可以采用例如DB值,然后创建一个fromDbValue类似于Jan答案中的静态函数.
public enum ReportTypeEnum {
R1(1),
R2(2),
R3(3),
R4(4),
R5(5),
R6(6),
R7(7),
R8(8);
private static Logger log = LoggerFactory.getLogger(ReportEnumType.class);
private static Map<Integer, ReportTypeEnum> lookup;
private Integer dbValue;
private ReportTypeEnum(Integer dbValue) {
this.dbValue = dbValue;
}
static {
try {
ReportTypeEnum[] vals = ReportTypeEnum.values();
lookup = new HashMap<Integer, ReportTypeEnum>(vals.length);
for (ReportTypeEnum rpt: vals)
lookup.put(rpt.getDbValue(), rpt);
}
catch (Exception e) {
// Careful, if any exception is thrown out of a static block, the class
// won't be initialized
log.error("Unexpected exception initializing " + ReportTypeEnum.class, e);
}
}
public static ReportTypeEnum fromDbValue(Integer dbValue) {
return lookup.get(dbValue);
}
public Integer getDbValue() {
return this.dbValue;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以在不更改查找的情况下更改顺序,反之亦然.
您可以使用静态查找表:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我使用的。我并不假装它比上面更简单的解决方案“效率”要低得多。当在上面的解决方案中使用无效的序数值时,它所做的是提供比“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);
}
Run Code Online (Sandbox Code Playgroud)