我在suggested on a blog上看到,在Java enum中使用getCode(int)
进行“反向查找”是一种合理的方法:
public enum Status {
WAITING(0),
READY(1),
SKIPPED(-1),
COMPLETED(5);
private static final Map<Integer,Status> lookup
= new HashMap<Integer,Status>();
static {
for(Status s : EnumSet.allOf(Status.class))
lookup.put(s.getCode(), s);
}
private int code;
private Status(int code) {
this.code = code;
}
public int getCode() { return code; }
public static Status get(int code) {
return lookup.get(code);
}
}
对我来说,静态映射和静态初始化器看起来都不是一个好主意,我的第一个想法是这样编写查找代码:
public enum Status {
WAITING(0),
READY(1),
SKIPPED(-1),
COMPLETED(5);
private int code;
private Status(int code) {
this.code = code;
}
public int getCode() { return code; }
public static Status get(int code) {
for(Status s : values()) {
if(s.code == code) return s;
}
return null;
}
}
这两种方法都有明显的问题吗?有没有推荐的方法来实现这种查找?
发布于 2011-03-16 02:33:08
来自谷歌Guava的Maps.uniqueIndex在构建查找地图方面非常方便。
更新:以下是在Java8中使用Maps.uniqueIndex
的示例:
public enum MyEnum {
A(0), B(1), C(2);
private static final Map<Integer, MyEnum> LOOKUP = Maps.uniqueIndex(
Arrays.asList(MyEnum.values()),
MyEnum::getStatus
);
private final int status;
MyEnum(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
@Nullable
public static MyEnum fromStatus(int status) {
return LOOKUP.get(status);
}
}
发布于 2011-03-16 02:34:07
尽管静态映射具有较高的开销,但它很好用,因为它提供了按code
进行的恒定时间查找。您的实现的查找时间随着枚举中元素的数量线性增加。对于小的枚举,这根本不会有太大的贡献。
这两种实现的一个问题是:null
实际上是Status
可以承担的一个隐藏的附加值。根据业务逻辑的规则,当查找“失败”时,返回实际的枚举值或抛出Exception
可能是有意义的。
发布于 2011-03-16 02:40:41
这里有一个更快的替代方案:
public enum Status {
WAITING(0),
READY(1),
SKIPPED(-1),
COMPLETED(5);
private int code;
private Status(int code) {
this.code = code;
}
public int getCode() { return code; }
public static Status get(int code) {
switch(code) {
case 0: return WAITING;
case 1: return READY;
case -1: return SKIPPED;
case 5: return COMPLETED;
}
return null;
}
}
当然,如果您希望以后能够添加更多常量,那么这并不是真正可维护的。
https://stackoverflow.com/questions/5316311
复制相似问题