java通过数字id获取枚举的最佳方法
我需要创建一个大约有300个值的枚举,并且能够通过id(int)获取其值。我目前有:
public enum Country {
DE(1), US(2), UK(3);
private int id;
private static Map<Integer, Country> idToCountry = new HashMap<>();
static {
for (Country c : Country.values()) {
idToCountry.put(c.id, c);
}
}
Country(int id) {
this.id = id;
}
public static Country getById(int id) {
return idToCountry.get(id);
}
}
这个枚举将被大量使用,所以我想知道这是否是性能方面最好的解决方案
我一遍又一遍地读http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html,但找不到描述时间的部分
static {
}
块被调用,如果保证只调用一次。是吗
# 1 楼答案
如果第一个国家id为
0
,且id增加了1
,则可以使用下一种方法:Enum.values()
返回元素的顺序与它们在enum中声明的顺序相同。但它应该被缓存,因为它每次被调用时都会创建新的数组李>请参见下面的代码:
更新:要获取国家id,应使用
ordinal()
方法。为了更清楚地获取id代码,可以在枚举中添加下一种方法:# 2 楼答案
首先,创建地图不需要静态块。您只需将代码添加到构造函数中,每个组件都会将自己添加到映射中。Enum始终是一个sigleton,因此您的构造函数保证只被调用一次(每个Enum值),而且您甚至不需要ID,因为Enum的方法public final int ordinal()在Enum中返回其从零开始的序列号。在你的例子中,序数是0代表DE,1代表US,2代表UK
下面是一个例子:
# 3 楼答案
静态初始值设定项块被调用一次when the class is initialized。它不能保证只被调用一次,但除非你在用类装入器做一些异国情调的事情
因此,从性能角度来看,您的方法可能是很好的。我建议的唯一改变是将字段
final
表示映射的另一种方法是将元素存储在数组(或列表)中:
然后可以通过元素索引查找它们:
这避免了为了调用
idToCountry.get(Integer)
而必须将id
框起来的性能损失当然,这需要您拥有非阴性ID(理想情况下,ID应该是合理连续的,以避免在国家之间存储大量
null
)# 4 楼答案
你也可以试试这个。这很简单
非常感谢