给定枚举,其中每个实例都与某个值相关联:
public enum SQLState
{
SUCCESSFUL_COMPLETION("00000"),
WARNING("01000");
private final String code;
SQLState(String code)
{
this.code = code;
}
}
如何构建有效反向查找的地图?我尝试了以下方法:
public enum SQLState
{
SUCCESSFUL_COMPLETION("00000"),
WARNING("01000");
private final String code;
private static final Map<String, SQLState> codeToValue = Maps.newHashMap();
SQLState(String code)
{
this.code = code;
codeToValue.put(code, this); // problematic line
}
}
但是Java抱怨:Illegal reference to static field from initializer
。也就是说,静态Map正在之后所有枚举值进行初始化,因此您无法从构造函数中引用它。有什么想法吗?
答案 0 :(得分:13)
使用:
static {
for (SQLState sqlState : values()){
codeToValue.put(sqlState.code, sqlState);
}
}
答案 1 :(得分:1)
当您使用Guava时,我建议使用以下代码:
public enum SQLState {
SUCCESSFUL_COMPLETION("00000"),
WARNING("01000"),
;
private final String code;
private SQLState(String code) {
this.code = code;
}
public static final Function<SQLState,String> EXTRACT_CODE = new Function<SQLState,String>() {
@Override
public String apply(SQLState input) {
return input.code;
}
};
public static final Map<String, SQLState> CODE_TO_VALUE = ImmutableMap.copyOf( Maps.uniqueIndex(EnumSet.allOf(SQLState.class), EXTRACT_CODE) );
public static void main(String[] args) {
System.out.println( SQLState.CODE_TO_VALUE.get("00000") );
}
}
按预期产生:“SUCCESSFUL_COMPLETION”
当你不能内联最终变量时,使用静态初始化器是很好的,但在这种情况下,使用Guava,你真的可以使用Guava函数的函数方法。
进一步模式,你可以在同一时间内使你的列表成为不可变的,如果你需要公开公开它,那就很好了
您还可以使用静态块使列表不可变,但在初始化最终列表之前需要填写临时列表。
检查 Maps uniqueIndex documentation这是一个非常酷的Guava函数,允许通过任何属性索引任何对象。 如果许多对象共享相同的属性值,您可以使用Multimaps.index,对于每个键,它将为您提供具有此属性的objets列表。
答案 2 :(得分:0)
在构造函数之前初始化static {...}块中的静态映射。查找静态初始化程序块。