假设我有一个包含 100 个值的枚举。为简单起见,举个例子:
public enum code
{
CODE_1("string1"),
CODE_2("string2"),
CODE_3("string3"),
CODE_4("string4"),
...
}
我想创建一个公共(public)方法来将已知格式的字符串(如“string1”、“string2”...)转换为适当的枚举值 CODE_1、CODE_2... 通常这是通过遍历所有值来完成的,如果找到匹配项,则返回该枚举值。 (详情可见in this question。)
但是,我担心定期循环所有值。这可能是一个巨大的瓶颈吗?如果不是 100 个元素,而是 1000 个呢?
作为我自己的练习,我尝试使用静态映射优化此查找,它可以确保给定任何字符串的 O(1) 查找时间。我喜欢这个额外的噱头,但如果确实有必要,我只想将它包含在我的代码中。您对使用迭代法与 map 法有何想法和发现?
public enum Code
{
...
//enum values
...
//The string-to-Code map
private static final Map<String,Code> CODE_MAP = populateMap();
private static Map<String,Code> populateMap()
{
Map<String,Code> map = new HashMap<String,Code>();
for(Code c : Code.values())
{
map.put(c.getCode(), c);
}
return map;
}
private String code;
private Code(String code)
{
this.code = code;
}
public String getCode()
{
return this.code;
}
public Code convertFromString(String code)
{
//assume that the given string is actually a key value in the map
return (Code) CODE_MAP.get(code);
}
}
最佳答案
你想要一个 Map<String, Code>
,但是如何整齐地填充它?枚举不允许您在初始化枚举实例之前初始化静态字段,但有一个巧妙的小技巧,称为 Initialization-on-demand holder idiom ,这使得使用此功能所需的静态初始化映射很容易实现:
public enum Code {
CODE_1("string1"),
CODE_2("string2"),
CODE_3("string3"),
// etc
;
private static class Holder {
static Map<String, Code> CODE_MAP = new HashMap<>();
}
private final String code;
private Code(String code) {
this.code = code;
Holder.CODE_MAP.put(code, this);
}
public String getCode() {
return this.code;
}
public Code convertFromString(String code) {
return Holder.CODE_MAP.get(code);
}
}
这是因为类加载器在初始化枚举类之前初始化了内部静态类,因此在枚举实例初始化期间分配映射准备加载。
没有循环。没有特殊的代码来加载 map (在构造函数中完成)。最少的代码。
关于java - 从 String 转换为具有大量值的 Java 枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27703119/