48 votes

Enum Java valueOf () avec plusieurs valeurs?

J'ai un problème en Java en utilisant les Énumérations. J'ai lu la documentation sur l'affectation de la valeur des paramètres pour les Énumérations. Mais, ma question est ce que sur plusieurs valeurs, est-il possible?

Ce que j'aimerais réaliser: J'ai un Enum pour les langues. Chaque langue est représentée par son nom et certains plus courte alias (pas toujours, et pas toujours le même nombre d'alias)

Voici un exemple:

public enum Language{
English("english", "eng", "en", "en_GB", "en_US"),
German("german", "de", "ge"),
Croatian("croatian", "hr", "cro"),
Russian("russian")
}

Puis-je définir un Enum comme cela et d'obtenir les bonnes valeurs enum par l'appel de la Langue.valueOf() ???

70voto

Flavio Points 5369

Ceci est probablement similaire à ce que vous essayez d'atteindre.

 public enum Language{
    English("english", "eng", "en", "en_GB", "en_US"),
    German("german", "de", "ge"),
    Croatian("croatian", "hr", "cro"),
    Russian("russian");

    private final List<String> values;

    Language(String ...values) {
        this.values = Arrays.asList(values);
    }

    public List<String> getValues() {
        return values;
    }
}
 

Rappelez-vous que les enums sont une classe comme les autres; English("english", "eng", "en", "en_GB", "en_US") appelle le constructeur enum.

Vous pouvez ensuite récupérer la valeur enum correspondant à une chaîne via une méthode de recherche (vous pouvez la réutiliser comme méthode statique dans l'énum).

 public static Language find(String name) {
    for (Language lang : Language.values()) {
        if (lang.getValues().contains(name)) {
            return lang;
        }
    }
    return null;
}
 

17voto

JoD. Points 188

Cartographie d'une chaîne à une valeur d'énumération est généralement ce que l' valueOf méthode statique est fait pour vous. Donc, si vous voulez-à-vis de cela avec l'utilisation de synonymes, vous aurez à développer quelque chose de similaire. Cependant, nous ne voulons pas donner le prétexte que l'on peut surcharger une méthode statique, donc nous avons juste un nom différent à cette fin: fromString doit être appropriée.

public enum Language { 
  ENGLISH("eng", "en", "en_GB", "en_US"),   
  GERMAN("de", "ge"),   
  CROATIAN("hr", "cro"),   
  RUSSIAN("ru"),
  BELGIAN("be",";-)");

  static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>(); 
  static { 
    for (Command type:Command.values()) { 
      // ignoring the case by normalizing to uppercase
      ALIAS_MAP.put(type.getKey().toUpper(),type); 
      for (String alias:type.aliases) ALIAS_MAP.put(alias.toUpper(),type); 
    } 
  } 

  static public boolean has(String value) { 
    // ignoring the case by normalizing to uppercase
    return ALIAS_MAP.containsKey(value.toUpper()); 
  } 

  static public Language fromString(String value) { 
    if (value == null) throw new NullPointerException("alias null"); 
    Command command = ALIAS_MAP.get(value); 
    if (command == null) throw new IllegalArgumentException("Not an alias: "+value); 
    return command; 
  } 

  private List<String> aliases; 
  private Language(String... aliases) { 
    this.aliases = Arrays.asList(aliases); 
  } 
} 

Un avantage de ce type de mise en œuvre, nous pouvons, comme le montre, aussi facilement mettre en œuvre l' has méthode statique pour tester si un alias est une partie de la valeur d'enum ensemble. Dans le même temps, nous avons appliqué quelques bonnes conventions de nommage:

  • les valeurs enum aller en majuscules, pour indiquer qu'ils sont en réalité statique finales (singleton cas).
  • dans le même temps, nous avons également mis à toutes les autres statique finale tout en majuscules.

Notez que nous n'avons pas à répéter le nom de la valeur d'enum lui-même: nous avons toujours considder son propre nom automatiquement (s'ajoute à la ALIAS_MAP), et en plus, nous normaliser tout en majuscules pour le rendre insensible à la casse.

Semble grand, mais tout en utilisant le protocole enum, il semble petite:

public void main() {
  Language myLanguage = Language.fromString("en_GB");
  if (myLanguage == Language.ENGLISH) {
    System.out.println("Yes, I know, you understand English!");
  }
} 

Maintenant, la raison pour laquelle nous sommes à l'aide de ALIAS_MAP est parce que nous intuitivily comprendre que pour optimiser valueOf de recherche les valeurs enum ont besoin d'être soutenus en quelque sorte avec une Carte déjà. Cependant, nous n'avons pas accès, ce qui nous permet en fin de réplication par notre propre. La Carte agit comme un indice d'offrir une simple recherche. Nous aurions pu utiliser d'autres propriétés que le nom de l'index pour une recherche. En fait, dans ce cas, nous utilisons d'autres propriétés: les alias que nous stockons par valeur. Nous utilisons les alias de chaque valeur d'enum pour construire le global (statique) de l'indice.

En ce moment, je ne peux pas confirmer si c'est vrai que le valueOf est soutenu par une Carte, mais nous avons tous pu imaginer facilement. De toute façon, les énumérations sont ouverts à beaucoup de moment de la compilation, optimisation, de sorte que le valueOf pourrait être remplacé en ligne avec quelque chose de totalement différent. Peut-être que c'est la raison pourquoi la Carte n'est même pas exposés.

3voto

Andy Pryor Points 4118

Bref non.

Le paramètre de la méthode valueOf () doit être uniquement la chaîne du type constant enum. Donc, il ne peut pas varier, ou rechercher des valeurs possibles. Voir le JavaDoc .

Vous devez écrire votre propre méthode d’utilitaire pour renvoyer le type d’énum approprié pour les valeurs données.

2voto

AlexR Points 60796

Je vous recommande de voir mes articles: http://java.dzone.com/articles/enum-tricks-customized-valueof et http://java.dzone.com/articles/enum-tricks-hierarchical-data

Bien que je ne suis pas sûr de comprendre exactement ce que vous voulez vraiment, je crois qu'au moins l'un de ces articles contiennent la réponse à votre question.

2voto

EJP Points 113412

Normaliser les données:

 public enum LanguageCode
{
  ENGLISH,
  GERMAN,
  CROATIAN,
  RUSSIAN,
  // ...
}
// (add whatever initialization you want to that
 

ensuite

 public enum Language{
  english(ENGLISH),
  eng(ENGLISH),
  en(ENGLISH),
  en_GB(ENGLISH),
  // ...
}
 

etc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X