如何将值映射回枚举?

时间:2011-04-01 15:33:55

标签: java enums guava

给定枚举,其中每个实例都与某个值相关联:

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正在之后所有枚举值进行初始化,因此您无法从构造函数中引用它。有什么想法吗?

3 个答案:

答案 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 {...}块中的静态映射。查找静态初始化程序块。