2011-04-01 107 views
10

由于每个实例都与某个值相关联的枚举:如何将值映射回枚举?

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抱怨:​​。也就是说,静态地图正在初始化之后的所有枚举值,所以你不能从构造函数中引用它。有任何想法吗?

回答

13

使用:

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

有关JLS中的规范示例,请参阅http://java.sun.com/docs/books/jls/third_edition/html/classes.html#324268 – 2011-04-01 15:42:34

0

的构造函数之前初始化静态地图静态{...}块。查找静态初始化块。

1

当您使用的番石榴,我建议使用下面的代码:

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”

使用静态初始化是好的,当你无法初始化最后的变量内联,但在这种情况下,与番石榴,你真的可以在功能方面与番石榴功能。

Furthermode,你让你的列表中,如果你需要公开揭露它,这是很好的同时一成不变

您也可以让你列表不变与静态块,但你需要初始化之前,以填补临时列表最终名单。


检查 Maps uniqueIndex documentation这是番石榴的一个非常酷的功能,通过它的任何属性的允许索引的对象。 如果许多对象共享相同的属性值,则可以使用Multimaps.index,对于每个键,它将为您提供具有此属性的objeets的列表。