sle*_*ske 107 java enums coding-style
当使用只能获取有限数量值的变量/参数时,我会尝试始终使用Java enum,如
public enum BonusType {
MONTHLY, YEARLY, ONE_OFF
}
Run Code Online (Sandbox Code Playgroud)
只要我留在我的代码中,就可以了.但是,我经常需要与其他使用普通int(或String)值的代码进行交互以达到相同的目的,或者我需要从/向数据库读取/写入数据,其中数据存储为数字或字符串.
在这种情况下,我想有一个方便的方法将每个枚举值与一个整数相关联,这样我就可以双向转换(换句话说,我需要一个"可逆的枚举").
从枚举到int很容易:
public enum BonusType {
public final int id;
BonusType(int id) {
this.id = id;
}
MONTHLY(1), YEARLY(2), ONE_OFF(3);
}
Run Code Online (Sandbox Code Playgroud)
然后我可以访问int值BonusType x = MONTHLY; int id = x.id;.
但是,我没有看到反向的好方法,即从int到enum.理想情况下,像
BonusType bt = BonusType.getById(2);
Run Code Online (Sandbox Code Playgroud)
我能想出的唯一解决方案是:
BonusType.values()用于填充映射"int - > enum",然后缓存并将其用于查找.会工作,但我必须将这个方法完全复制到我使用的每个枚举中:-(.对于这样一个简单的(?)问题,这两种方法看起来都非常尴尬.
还有其他想法/见解吗?
aio*_*obe 324
yourEnum.ordinal()
Run Code Online (Sandbox Code Playgroud)
EnumType.values()[someInt]
Run Code Online (Sandbox Code Playgroud)
EnumType.valueOf(yourString)
Run Code Online (Sandbox Code Playgroud)
yourEnum.name()
Run Code Online (Sandbox Code Playgroud)
旁注:
正如您正确指出的那样,ordinal()从版本到版本可能"不稳定".这就是为什么我总是将常量存储为数据库中的字符串的确切原因.(实际上,当使用MySql时,我将它们存储为MySql枚举!)
Jef*_*eff 37
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案很好,并且不需要"摆弄反射",因为它基于所有枚举类型隐式继承Enum接口的事实.
小智 27
我在网上发现了这个,它非常有用且易于实现.这个解决方案不是我做的
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);
}
Run Code Online (Sandbox Code Playgroud)
}
似乎这个问题的答案已经过时了Java 8的发布.
public enum AccessLevel {
PRIVATE("private", 0),
PUBLIC("public", 1),
DEFAULT("default", 2);
AccessLevel(final String name, final int value) {
this.name = name;
this.value = value;
}
private final String name;
private final int value;
public String getName() {
return name;
}
public int getValue() {
return value;
}
static final Map<String, AccessLevel> names = Arrays.stream(AccessLevel.values())
.collect(Collectors.toMap(AccessLevel::getName, Function.identity()));
static final Map<Integer, AccessLevel> values = Arrays.stream(AccessLevel.values())
.collect(Collectors.toMap(AccessLevel::getValue, Function.identity()));
public static AccessLevel fromName(final String name) {
return names.get(name);
}
public static AccessLevel fromValue(final int value) {
return values.get(value);
}
}
Run Code Online (Sandbox Code Playgroud)
为了节省编写每个Enum的样板代码或重复代码的繁琐工作,我改用Apache Commons Lang ValuedEnum。
定义:
public class NRPEPacketType extends ValuedEnum {
public static final NRPEPacketType TYPE_QUERY = new NRPEPacketType( "TYPE_QUERY", 1);
public static final NRPEPacketType TYPE_RESPONSE = new NRPEPacketType( "TYPE_RESPONSE", 2);
protected NRPEPacketType(String name, int value) {
super(name, value);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
int-> ValuedEnum:
NRPEPacketType packetType =
(NRPEPacketType) EnumUtils.getEnum(NRPEPacketType.class, 1);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
121604 次 |
| 最近记录: |