问题
使用只能获取有限数量值的变量/参数时,我尝试始终使用Java的enum
,如
public enum BonusType {
MONTHLY, YEARLY, ONE_OFF
}
只要我留在我的代码中,就可以了。但是,我经常需要与使用plainint
(或String
)值的其他代码进行交互以达到相同的目的,或者我需要从/向数据库读取/写入数据,其中数据存储为数字或字符串。
在这种情况下,我想有一种方便的方法将每个枚举值与一个整数相关联,这样我就可以转换两种方式(换句话说,我需要一个"可逆枚举")。
从枚举到int很容易:
public enum BonusType {
public final int id;
BonusType(int id) {
this.id = id;
}
MONTHLY(1), YEARLY(2), ONE_OFF(3);
}
然后我可以访问int值asBonusType x = MONTHLY; int id = x.id;
。
但是,我看不出相反的好方法,即从int到enum。理想情况下,像
BonusType bt = BonusType.getById(2);
我能想出的唯一解决方案是:
- 将查找方法放入枚举中,使用BonusType.values()填充 Map "int - > enum",然后缓存并使用它进行查找。会工作,但我必须将这个方法完全复制到我使用的每个枚举中:-(。
- 将查找方法放入静态实用程序类中。然后我只需要一个"查找"方法,但我必须摆弄反射才能让它适用于任意枚举。
对于这样一个简单的(?)问题,这两种方法看起来都非常尴尬。
还有其他想法/见解吗?
#1 热门回答(318 赞)
enum→int
yourEnum.ordinal()
int→enum
EnumType.values()[someInt]
String→enum
EnumType.valueOf(yourString)
enum→String
yourEnum.name()
附注:
正如你正确指出的那样,ordinal()
可能在版本之间"不稳定"。这就是为什么我总是将常量存储为数据库中的字符串的确切原因。 (实际上,当使用MySql时,我将它们存储为MySql enums!)
#2 热门回答(35 赞)
http://www.javaspecialists.co.za/archive/Issue113.html
解决方案的开头与你的类似,int值作为枚举定义的一部分。然后他继续创建一个基于泛型的查找工具:
public class ReverseEnumMap<V extends Enum<V> & EnumConverter> {
private Map<Byte, V> map = new HashMap<Byte, V>();
public ReverseEnumMap(Class<V> valueType) {
for (V v : valueType.getEnumConstants()) {
map.put(v.convert(), v);
}
}
public V get(byte num) {
return map.get(num);
}
}
这个解决方案很好,不需要"摆弄反射",因为它基于所有枚举类型隐式继承Enum接口的事实。
#3 热门回答(26 赞)
我在网上发现了这个,它非常有用且易于实现。这个解决方案不是我做的
http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks
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);
}
}