2011-04-01 6 views
10

Étant donnée une ENUM où chaque instance est associée à une certaine valeur:Comment mapper une valeur en une énumération?

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

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

Comment puis-je construire une carte pour un look-up inverse efficace? J'ai essayé les éléments suivants:

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 
    } 
} 

mais Java se plaint: Illegal reference to static field from initializer. C'est-à-dire que la Map statique est en cours d'initialisation après toutes les valeurs enum de sorte que vous ne pouvez pas la référencer depuis le constructeur. Des idées?

Répondre

13

utilisation:

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

Pour l'exemple canonique dans la JLS, voir http://java.sun.com/docs/books/jls/third_edition/html/classes.html#324268 –

0

Initialiser la carte statique dans le bloc statique {...} avant que le constructeur. Recherchez les blocs d'initialisation statiques.

1

Comme vous utilisez goyave, je recommande d'utiliser le code suivant:

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

} 

Ce produit comme prévu: « SUCCESSFUL_COMPLETION »

L'utilisation initialiseur statique est agréable quand vous ne pouvez pas initialiser les variables finales inline, mais dans ce cas, avec Guava, vous pouvez vraiment, dans une approche fonctionnelle avec des fonctions de goyave.

Furthermode, vous faites votre liste immuable dans le même temps ce qui est agréable si vous avez besoin d'exposer publiquement

Vous pouvez également faire votre liste immuable avec un bloc statique, mais vous devez remplir une liste temporaire avant d'initialiser la liste finale.


Vérifiez la Maps uniqueIndex documentation qui est une fonction de goyave vraiment cool qui permet d'indexer un objet par l'un de ses attributs. Si plusieurs objets partagent la même valeur d'attribut, vous pouvez utiliser Multimaps.index qui, pour chaque clé, vous donnera une liste d'objets ayant cet attribut.

Questions connexes