web-dev-qa-db-fra.com

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

Voici mon problème - je cherche (s'il existe même) 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 me rends compte qu’une ArrayList de Strings serait la meilleure voie ici, mais je dois faire passer mon contenu enum à travers un commutateur/un dossier ailleurs. D'où mon problème.

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

137
Jared

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’aurez plus à vous soucier d’ajouter ultérieurement des valeurs d’énumération, elles sont toutes vérifiées.

Modifier: Si l'énumération est très grande, vous pouvez coller les valeurs dans un hachage:

public static HashSet<String> getEnums() {

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

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

  return values;
}

Ensuite, vous pouvez simplement faire: values.contains("your string") qui renvoie vrai ou faux.

174
Richard H

Utilisez plutôt la librairie lang3 de Apache commons

 EnumUtils.isValidEnum(MyEnum.class, myValue)
199
RaphC

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 peut-être mieux d'utiliser une boucle simple, comme d'autres l'ont montré - si vos enums contiennent plusieurs valeurs, peut-être builda HashSet ou similaire de vos valeurs enum converti en chaîne et interroge plutôt HashSet.

46
nos

Si vous utilisez Java 1.8, vous pouvez choisir Stream + Lambda pour implémenter ceci:

public enum Period {
    DAILY, WEEKLY
};

//This is recommended
Arrays.stream(Period.values()).anyMatch((t) -> t.name().equals("DAILY1"));
//May throw Java.lang.IllegalArgumentException
Arrays.stream(Period.values()).anyMatch(Period.valueOf("DAILY")::equals);
26
Hao Ma

Guavas Enums pourrait être votre ami

Comme par exemple cette:

enum MyData {
    ONE,
    TWO
}

@Test
public void test() {

    if (!Enums.getIfPresent(MyData.class, "THREE").isPresent()) {
        System.out.println("THREE is not here");
    }
}
18
H6.

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

};
16
Devashish Bansal

Vous pouvez d’abord convertir l’énumération en List puis utiliser la méthode list contient

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

List choices = Arrays.asList(Choices.values());

//compare with enum value 
if(choices.contains(Choices.A1)){
   //do something
}

//compare with String value
if(choices.contains(Choices.valueOf("A1"))){
   //do something
}
9
Bikram

Vous pouvez utiliser ceci

Votre Enum {A1, A2, B1, B2}

boolean contains(String str){ 
    return Sets.newHashSet(YourEnum.values()).contains(str);
}                                  

La mise à jour suggérée par @ wightwulf1944 est incorporée pour rendre la solution plus efficace.

7
greperror

Quelques bibliothèques ont été mentionnées ici, mais celle que je cherchais me manque: le printemps!

Il y a le ObjectUtils # containsConstant qui est insensible à la casse par défaut, mais peut être strict si vous le souhaitez. Il est utilisé comme ceci:

if(ObjectUtils.containsConstant(Choices.values(), "SOME_CHOISE", true)){
// do stuff
}

Remarque: J'ai utilisé la méthode surchargée ici pour montrer comment utiliser le contrôle sensible à la casse. Vous pouvez omettre le booléen pour avoir un comportement insensible à la casse.

Soyez prudent avec les grands enums, car ils n'utilisent pas l'implémentation de Map comme le font certains ...

En prime, il fournit également une variante insensible à la casse de la valeur valueOf: ObjectUtils # caseInsensitiveValueOf

7
Pim Hazebroek

Quelques hypothèses:
1) Aucun essai/attrape, car c'est un contrôle de flux exceptionnel
2) La méthode 'contient' doit être rapide, car elle fonctionne généralement plusieurs fois.
3) L'espace n'est pas limité (commun pour les solutions ordinaires)

import Java.util.HashSet;
import Java.util.Set;

enum Choices {
    a1, a2, b1, b2;

    private static Set<String> _values = new HashSet<>();

    // O(n) - runs once
    static{
        for (Choices choice : Choices.values()) {
            _values.add(choice.name());
        }
    }

    // O(1) - runs several times
    public static boolean contains(String value){
        return _values.contains(value);
    }
}
6
AndreyP

Je ne pense pas, mais vous pouvez faire quelque chose comme ceci:

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

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

Modifier:

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

3
jluzwick

Pourquoi ne pas associer la réponse de Pablo à un valueOf ()?

public enum Choices
{
    a1, a2, b1, b2;

    public static boolean contains(String s) {
        try {
            Choices.valueOf(s);
            return true;
        } catch (Exception e) {
            return false;
        }
}
2
Karthik. V

Si vous utilisez Apache Commons (ou êtes prêt à le faire), vous pouvez le vérifier avec:

ArrayUtils.contains(choices.values(), value)
2
deamon

Celui-ci fonctionne pour moi:

Arrays.asList(YourEnum.values()).toString().contains("valueToCheck");
1
EDiaz

Cette approche peut être utilisée pour vérifier n'importe quel Enum, vous pouvez l'ajouter à une classe Utils:

public static <T extends Enum<T>> boolean enumContains(Class<T> enumerator, String value)
{
    for (T c : enumerator.getEnumConstants()) {
        if (c.name().equals(value)) {
            return true;
        }
    }
    return false;
}

Utilisez-le de cette façon:

boolean isContained = Utils.enumContains(choices.class, "value");
1
António Almeida

J'ai créé le prochain cours pour cette validation

public class EnumUtils {

    public static boolean isPresent(Enum enumArray[], String name) {
        for (Enum element: enumArray ) {
            if(element.toString().equals(name))
                return true;
        }
        return false;
    }

}

exemple d'utilisation:

public ArrivalEnum findArrivalEnum(String name) {

    if (!EnumUtils.isPresent(ArrivalEnum.values(), name))
        throw new EnumConstantNotPresentException(ArrivalEnum.class,"Arrival value must be 'FROM_AIRPORT' or 'TO_AIRPORT' ");

    return ArrivalEnum.valueOf(name);
}
1

Si vous utilisez Java 8 ou une version ultérieure, procédez comme suit:

boolean isPresent(String testString){
      return Stream.of(Choices.values()).map(Enum::name).collect(Collectors.toSet()).contains(testString);
}
0
Chirag C

Avec la goyave, c'est encore plus simple:

boolean isPartOfMyEnum(String myString){

return Lists.newArrayList(MyEnum.values().toString()).contains(myString);

}
0
chaiyachaiya
  Set.of(CustomType.values())
     .contains(customTypevalue) 
0
Dmitry Ovcharenko

Vous pouvez utiliser valueOf("a1") si vous souhaitez rechercher par chaîne.

0
Amir Afghani
com.google.common.collect.Sets.newHashSet(MyEnum.values()).contains("myValue")
0
cnmuc

C'est une énumération, ce sont des valeurs constantes, donc si c'est dans une instruction switch, ça ne fait que quelque chose comme:

case: val1
case: val2

Aussi, pourquoi auriez-vous besoin de savoir ce qui est déclaré comme une constante?

0
Woot4Moo

Ceci combine toutes les approches des méthodes précédentes et devrait avoir des performances équivalentes. Il peut être utilisé pour n’importe quelle énumération, insère la solution "Éditer" de @Richard H et utilise Exceptions pour les valeurs invalides telles que @bestsss. Le seul compromis est que la classe doit être spécifiée, mais cela transforme cela en une ligne double.

import Java.util.EnumSet;

public class HelloWorld {

static enum Choices {a1, a2, b1, b2}

public static <E extends Enum<E>> boolean contains(Class<E> _enumClass, String value) {
    try {
        return EnumSet.allOf(_enumClass).contains(Enum.valueOf(_enumClass, value));    
    } catch (Exception e) {
        return false; 
    }
}

public static void main(String[] args) {
    for (String value : new String[] {"a1", "a3", null}) {
        System.out.println(contains(Choices.class, value));
    }
}

}

0
user2910265

solution pour vérifier si la valeur est présente et obtenir une valeur enum en retour:

protected TradeType getEnumType(String tradeType) {
    if (tradeType != null) {
        if (EnumUtils.isValidEnum(TradeType.class, tradeType)) {
            return TradeType.valueOf(tradeType);
        }
    }
    return null;
}
0
Amar Magar