256 votes

Java : Vérifier si l'enum contient une chaîne donnée ?

Voici mon problème - je cherche (s'il existe) l'équivalent enum de ArrayList.contains(); .

Voici un exemple de mon problème de code :

enum choices {a1, a2, b1, b2};

if(choices.???(a1)}{
//do this
} 

Maintenant, je réalise qu'une ArrayList de Strings serait la meilleure solution ici, mais je dois faire passer le contenu de mon enum par un switch/case ailleurs. D'où mon problème.

En supposant que quelque chose comme ça n'existe pas, comment pourrais-je m'y prendre ?

0 votes

La commutation/case avec les chaînes de caractères est implémentée à partir de Java 7

317voto

RaphC Points 131

Utilisez la librairie lang3 d'Apache Commons à la place.

 EnumUtils.isValidEnum(MyEnum.class, myValue)

46 votes

Note pour ceux qui sont intéressés, l'implémentation sous-jacente qu'ils ont utilisée est simplement la solution try/catch (@since 3.0 @version $Id : EnumUtils.java 1199894 2011-11-09 17:53:59Z ggregory $).

2 votes

Cela rend mon code plus simple, donc je ne me soucie pas de savoir s'il utilise les exceptions pour le contrôle de flux (ils ne devraient vraiment pas)... Ce serait bien s'ils changeaient cela.

1 votes

261voto

Richard H Points 11693

Cela devrait le faire :

public static boolean contains(String test) {

    for (Choice c : Choice.values()) {
        if (c.name().equals(test)) {
            return true;
        }
    }

    return false;
}

De cette façon, vous n'avez pas à vous soucier d'ajouter des valeurs d'enum supplémentaires plus tard, elles sont toutes vérifiées.

Editar: Si l'énumération est très grande, vous pouvez placer les valeurs dans un HashSet :

public static HashSet<String> getEnums() {

  HashSet<String> values = new HashSet<String>();

  for (Choice c : Choice.values()) {
      values.add(c.name());
  }

  return values;
}

Alors tu peux juste faire : values.contains("your string") qui renvoie vrai ou faux.

17 votes

C'est une implémentation très pauvre.. : Choice.valueOf(test) est ce que vous voulez (avec try/catch).

0 votes

Vraiment ? Vous préférez lancer une exception ? Certainement pas. Si l'énumération devient très grande, vous pourriez utiliser une carte.

0 votes

L'enum va en effet devenir très grande (1000+). Que suggérez-vous ?

67voto

nos Points 102226

Vous pouvez utiliser Enum.valueOf()

enum Choices{A1, A2, B1, B2};

public class MainClass {
  public static void main(String args[]) {
    Choices day;

    try {
       day = Choices.valueOf("A1");
       //yes
    } catch (IllegalArgumentException ex) {  
        //nope
  }
}

Si vous vous attendez à ce que la vérification échoue souvent, vous feriez mieux d'utiliser une simple boucle comme d'autres l'ont montré - si vos enums contiennent beaucoup de valeurs, peut-être en construisant un HashSet ou une valeur similaire de vos valeurs d'énumération convertie en chaîne de caractères et interrogez-la. HashSet à la place.

15 votes

Je ne pense pas que l'exception soit le meilleur choix dans un tel cas.

7 votes

Try and Catch devrait être le dernier recours. Try and Catch est trop cher

4 votes

En plus d'être coûteux, le fait de s'appuyer sur des exceptions d'exécution pour exécuter la logique métier n'est pas aussi lisible. En ce qui concerne les exceptions vérifiées, c'est différent, car elles font partie de l'activité.

19voto

Encore mieux :

enum choices {
   a1, a2, b1, b2;

  public static boolean contains(String s)
  {
      for(choices choice:values())
           if (choice.name().equals(s)) 
              return true;
      return false;
  } 

};

0 votes

Merci pour cette solution optimiste

3voto

jluzwick Points 1202

Je ne pense pas qu'il y en ait, mais vous pouvez faire quelque chose comme ça :

enum choices {a1, a2, b1, b2};

public static boolean exists(choices choice) {
   for(choice aChoice : choices.values()) {
      if(aChoice == choice) {
         return true;
      }
   }
   return false;
}

Editar:

Veuillez consulter la version de Richard, qui est plus appropriée, car elle ne fonctionnera pas si vous ne la convertissez pas pour utiliser Strings, ce que fait Richards.

0 votes

Mais je pense que l'OP veut tester une corde ?

0 votes

Oui, haha. Cette méthode ne serait pas très efficace car nous savons déjà que le choix est dans les enums. Votre modification est plus correcte.

1 votes

Si vous souhaitez travailler sur un sous-ensemble des enums eux-mêmes (et non sur leurs noms), il est préférable de se tourner vers EnumSet. download.oracle.com/javase/6/docs/api/java/util/EnumSet.html

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