开发者

How to map a value back to an enum?

Given an enum where each instance is associated with some value:

public enum SQLState
{
  SUCCESSFUL_COMPLETION("00000"),
  WARNING("01000");

  private final String code;
  SQLState(String code)
  {
    this.code = code;
  }
}

How can I construct a Map for efficient reverse look-ups? I tried the following:

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); // problem开发者_运维问答atic line
  }
}

but Java complains: Illegal reference to static field from initializer. That is, the static Map is being initialized after all enum values so you cannot reference it from the constructor. Any ideas?


use:

static {
  for (SQLState sqlState : values()){
     codeToValue.put(sqlState.code, sqlState);
  }
}


As you are using Guava, i recommend using the following code:

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") );
    }

}

This produces as expected: "SUCCESSFUL_COMPLETION"

Using static initializer is nice when you can't init the final variables inline, but in this case, with Guava, you really can, in a functionnal approach with Guava functions.

Furthermode, you make your list immutable in the same time which is nice if you need to expose it publicly

You can also make your list immutable with a static block but you need to fill a temporary list before initializing the final list.


Check the Maps uniqueIndex documentation which is a really cool function of Guava that permits to index any object by any of its attribute. In case many objects are sharing the same attribute value, you can use Multimaps.index which, for each key, will give you a list of objets having this attribute.


Initialize the static map in static{...} block before the constructor. Look up static initializer blocks.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜