Pergunta

Say Eu tenho um enum que é apenas

public enum Blah {
    A, B, C, D
}

e eu gostaria de encontrar o valor de enumeração de uma corda, por exemplo "A" que seria Blah.A. Como seria possível fazer isso?

É o Enum.valueOf() o método que eu preciso? Se assim for, como eu ia usar isso?

Foi útil?

Solução

Sim, Blah.valueOf("A") lhe dará Blah.A.

Note que o nome deve ser um exata jogo, inclusive o caso:. Blah.valueOf("a") e Blah.valueOf("A ") tanto lançar uma IllegalArgumentException

O valueOf() métodos estáticos e values() são criados em tempo de compilação e não aparecem no código-fonte. Eles aparecem em Javadoc, embora; por exemplo, Dialog.ModalityType mostra ambos os métodos .

Outras dicas

Outra solução se o texto não é o mesmo para o valor de enumeração:

public enum Blah {
    A("text1"),
    B("text2"),
    C("text3"),
    D("text4");

    private String text;

    Blah(String text) {
        this.text = text;
    }

    public String getText() {
        return this.text;
    }

    public static Blah fromString(String text) {
        for (Blah b : Blah.values()) {
            if (b.text.equalsIgnoreCase(text)) {
                return b;
            }
        }
        return null;
    }
}

Aqui está um uso bacana utilidade I:

/**
 * A common method for all enums since they can't have another base class
 * @param <T> Enum type
 * @param c enum type. All enums must be all caps.
 * @param string case insensitive
 * @return corresponding enum, or null
 */
public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) {
    if( c != null && string != null ) {
        try {
            return Enum.valueOf(c, string.trim().toUpperCase());
        } catch(IllegalArgumentException ex) {
        }
    }
    return null;
}

Em seguida, na minha classe enum Eu costumo ter este para salvar alguns digitando:

public static MyEnum fromString(String name) {
    return getEnumFromString(MyEnum.class, name);
}

Se o seu enums não são todos os tampões, basta alterar a linha Enum.valueOf.

Pena que eu não posso usar T.class para Enum.valueOf como T é apagada.

Você também deve ter cuidado com o seu caso. Deixe-me explicar: fazendo obras Blah.valueOf("A"), mas Blah.valueOf("a") não vai funcionar. Então, novamente Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) iria funcionar.

Editar
Mudou toUpperCase para toUpperCase(Locale.ENGLISH) baseado em tc. comentário eo java docs

edit2 No Android, você deve usar Locale.US , como sulai pontos fora .

Use o padrão de Joshua Bloch, Effective Java :

(simplificado por brevidade)

enum MyEnum {
    ENUM_1("A"),
    ENUM_2("B");

    private String name;

    private static final Map<String,MyEnum> ENUM_MAP;

    MyEnum (String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    // Build an immutable map of String name to enum pairs.
    // Any Map impl can be used.

    static {
        Map<String,MyEnum> map = new ConcurrentHashMap<String, MyEnum>();
        for (MyEnum instance : MyEnum.values()) {
            map.put(instance.getName(),instance);
        }
        ENUM_MAP = Collections.unmodifiableMap(map);
    }

    public static MyEnum get (String name) {
        return ENUM_MAP.get(name);
    }
}

Veja também:

o Oracle Java Exemplo usando Enum e Mapa de casos

ordem de execução das de blocos estáticos em um tipo Enum

Como posso pesquisa um enum Java de seu valor de Cordas

Aqui está um método que pode fazê-lo por qualquer Enum, e é insensível caso.

/** 
 * Finds the value of the given enumeration by name, case-insensitive. 
 * Throws an IllegalArgumentException if no match is found.  
 **/
public static <T extends Enum<T>> T valueOfIgnoreCase(
        Class<T> enumeration, String name) {

    for (T enumValue : enumeration.getEnumConstants()) {
        if (enumValue.name().equalsIgnoreCase(name)) {
            return enumValue;
        }
    }

    throw new IllegalArgumentException(String.format(
        "There is no value with name '%s' in Enum %s",
        name, enumeration.getName()
    ));
}

Usando Blah.valueOf(string) é melhor, mas você pode usar Enum.valueOf(Blah.class, string) também.

Se você não quer escrever o seu próprio uso utilitário Google de biblioteca:

Enums.getIfPresent(Blah.class, "A")

Ao contrário da construído em função de java que lhe permite verificar se um está presente em Blah e não lançar uma exceção.

Meus 2 centavos aqui: usando Java8 Streams + verificando uma seqüência exata:

public enum MyEnum {
    VALUE_1("Super"),
    VALUE_2("Rainbow"),
    VALUE_3("Dash"),
    VALUE_3("Rocks");

    private final String value;

    MyEnum(String value) {
        this.value = value;
    }

    /**
     * @return the Enum representation for the given string.
     * @throws IllegalArgumentException if unknown string.
     */
    public static MyEnum fromString(String s) throws IllegalArgumentException {
        return Arrays.stream(MyEnum.values())
                .filter(v -> v.value.equals(s))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("unknown value: " + s));
    }
}

EDIT ** **

Renomeada a função para fromString() desde nomeá-lo usando essa convenção, você vai obter alguns benefícios de linguagem Java em si; por exemplo:

  1. conversão direta de tipos em HeaderParam anotação

Em Java 8 ou posterior, usando Streams :

public enum Blah
{
    A("text1"),
    B("text2"),
    C("text3"),
    D("text4");

    private String text;

    Blah(String text) {
        this.text = text;
    }

    public String getText() {
        return this.text;
    }

    public static Optional<Blah> fromText(String text) {
        return Arrays.stream(values())
          .filter(bl -> bl.text.equalsIgnoreCase(text))
          .findFirst();
    }
}

Você pode precisar o seguinte:

public enum ObjectType {
    PERSON("Person");

    public String parameterName;

    ObjectType(String parameterName) {
        this.parameterName = parameterName;
    }

    public String getParameterName() {
        return this.parameterName;
    }

    //From String method will return you the Enum for the provided input string
    public static ObjectType fromString(String parameterName) {
        if (parameterName != null) {
            for (ObjectType objType : ObjectType.values()) {
                if (parameterName.equalsIgnoreCase(objType.parameterName)) {
                    return objType;
                }
            }
        }
        return null;
    }
}

One More Adição:

   public static String fromEnumName(String parameterName) {
        if (parameterName != null) {
            for (DQJ objType : DQJ.values()) {
                if (parameterName.equalsIgnoreCase(objType.name())) {
                    return objType.parameterName;
                }
            }
        }
        return null;
    }

Isto irá devolver-lhe o valor por um nome Stringified Enum Por exemplo se você fornecer "pessoa" no fromEnumName ele vai retornar o valor de Enum ou seja, "Pessoa"

Outra maneira de fazer isso usando implícita método estático name() de Enum. nome vai retornar a string exata usada para criar essa enumeração que pode ser usado para verificar contra corda desde que:

public enum Blah {

    A, B, C, D;

    public static Blah getEnum(String s){
        if(A.name().equals(s)){
            return A;
        }else if(B.name().equals(s)){
            return B;
        }else if(C.name().equals(s)){
            return C;
        }else if (D.name().equals(s)){
            return D;
        }
        throw new IllegalArgumentException("No Enum specified for this string");
    }
}

Testing:

System.out.println(Blah.getEnum("B").name());

//it will print B  B

inspiração: 10 Exemplos de Enum em Java

Solução usando bibliotecas de goiaba. Método getPlanet () é insensível caso, assim getPlanet ( "Mercury") irá retornar Planet.MERCURY.

package com.universe.solarsystem.planets;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Enums;
import com.google.common.base.Optional;

//Pluto and Eris are dwarf planets, who cares!
public enum Planet {
   MERCURY,
   VENUS,
   EARTH,
   MARS,
   JUPITER,
   SATURN,
   URANUS,
   NEPTUNE;

   public static Planet getPlanet(String name) {
      String val = StringUtils.trimToEmpty(name).toUpperCase();
      Optional <Planet> possible = Enums.getIfPresent(Planet.class, val);
      if (!possible.isPresent()) {
         throw new IllegalArgumentException(val + "? There is no such planet!");
      }
      return possible.get();
   }
}

Para adicionar as respostas anteriores, e abordar algumas das discussões em torno nulos e NPE Estou usando goiaba Opcionais para lidar com casos ausentes / inválido. Isso funciona muito bem para a URI / parâmetro de análise.

public enum E {
    A,B,C;
    public static Optional<E> fromString(String s) {
        try {
            return Optional.of(E.valueOf(s.toUpperCase()));
        } catch (IllegalArgumentException|NullPointerException e) {
            return Optional.absent();
        }
    }
}

Para quem não sabe, aqui está mais algumas informações sobre evitando nulo com Opcional: https: // code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional

Em Java 8 o padrão Mapa estática é ainda mais fácil e é o meu método preffered. Se você quiser usar o Enum com Jackson você pode substituir toString eo uso que em vez de nome, em seguida, anotar com @JsonValue

public enum MyEnum {
    BAR,
    BAZ;
    private static final Map<String, MyEnum> MAP = Stream.of(MyEnum.values()).collect(Collectors.toMap(Enum::name, Function.identity()));
    public static MyEnum fromName(String name){
        return MAP.get(name);
    }
}

public enum MyEnumForJson {
    BAR("bar"),
    BAZ("baz");
    private static final Map<String, MyEnumForJson> MAP = Stream.of(MyEnumForJson.values()).collect(Collectors.toMap(Object::toString, Function.identity()));
    private final String value;

    MyEnumForJson(String value) {
        this.value = value;
    }

    @JsonValue
    @Override
    public String toString() {
        return value;
    }

    public static MyEnumForJson fromValue(String value){
        return MAP.get(value);
    }
}
public static MyEnum getFromValue(String value) {
    MyEnum resp = null;
    MyEnum nodes[] = values();
    for(int i = 0; i < nodes.length; i++) {
        if(nodes[i].value.equals(value)) {
            resp = nodes[i];
            break;
        }
    }
    return resp;
}

O (1) método inspirado a partir do código gerado a poupança que utilizam um hashmap.

public enum USER {
        STUDENT("jon",0),TEACHER("tom",1);

        private static final Map<String, Integer> map = new HashMap<>();

        static {
                for (USER user : EnumSet.allOf(USER.class)) {
                        map.put(user.getTypeName(), user.getIndex());
                }
        }

        public static int findIndexByTypeName(String typeName) {
                return map.get(typeName);
        }

        private USER(String typeName,int index){
                this.typeName = typeName;
                this.index = index;
        }
        private String typeName;
        private int index;
        public String getTypeName() {
                return typeName;
        }
        public void setTypeName(String typeName) {
                this.typeName = typeName;
        }
        public int getIndex() {
                return index;
        }
        public void setIndex(int index) {
                this.index = index;
        }

}

java.lang.Enum define vários métodos úteis, que está disponível a todos os tipos de enumeração em Java:

  • Você pode usar o método name() para obter o nome de quaisquer constantes enum. literal string usada para constantes gravação enum é o seu nome.
  • método mesma forma values() pode ser usado para obter uma matriz de todas as constantes enum de um tipo Enum.
  • E para a pergunta, você pode usar o método valueOf() para converter qualquer String para constantes Enum em Java, como mostrado abaixo.
public class EnumDemo06 {
    public static void main(String args[]) {
        Gender fromString = Gender.valueOf("MALE");
        System.out.println("Gender.MALE.name() : " + fromString.name());
    }

    private enum Gender {
        MALE, FEMALE;
    }
}

Output:
Gender.MALE.name() : MALE

Neste trecho de código, o método valueOf() retorna uma constante Enum Gender.MALE, chamando o nome em que os retornos "MALE".

commons-lang biblioteca de Apache tem uma função estática org.apache.commons.lang3.EnumUtils.getEnum que irá mapear uma string para o seu tipo de Enum. Mesma resposta essencialmente como Geoffreys mas por rolo seu próprio quando está lá fora na selva já.

Adicionando para a resposta mais votados, com um utilitário útil ...

valueOf() lança duas exceções diferentes nos casos em que ele não gosta de sua entrada.

  • IllegalArgumentException
  • NullPointerExeption

Se suas necessidades são tais que você não tem qualquer garantia de que o seu Cordas vai certamente coincidir com um valor de enumeração, por exemplo, se os dados de cadeia vem de um banco de dados e pode conter versão antiga do enum, então você vai precisar para lidar com estes muitas vezes ...

Então aqui está um método reutilizável eu escrevi o que nos permite definir um Enum padrão a ser devolvido se a cadeia passamos não corresponde.

private static <T extends Enum<T>> T valueOf( String name , T defaultVal) {
        try {
            return Enum.valueOf(defaultVal.getDeclaringClass() , name);
        } catch (IllegalArgumentException | NullPointerException e) {
            return defaultVal;
        }
    }

Use-o assim:

public enum MYTHINGS {
    THINGONE,
    THINGTWO
}

public static void main(String [] asd) {
  valueOf("THINGTWO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGTWO
  valueOf("THINGZERO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGONE
}

Sobre o quê?

public enum MyEnum {
    FIRST,
    SECOND,
    THIRD;

    public static Optional<MyEnum> fromString(String value){
        try{
            return Optional.of(MyEnum.valueOf(value));
        }catch(Exception e){
            return Optional.empty();
        }
    }
}

Outra utilidade capturando de forma inversa. Usando um valor que identificam que Enum, não do seu nome.

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.EnumSet;

public class EnumUtil {

    /**
     * Returns the <code>Enum</code> of type <code>enumType</code> whose a 
     * public method return value of this Enum is 
     * equal to <code>valor</code>.<br/>
     * Such method should be unique public, not final and static method 
     * declared in Enum.
     * In case of more than one method in match those conditions
     * its first one will be chosen.
     * 
     * @param enumType
     * @param value
     * @return 
     */
    public static <E extends Enum<E>> E from(Class<E> enumType, Object value) {
        String methodName = getMethodIdentifier(enumType);
        return from(enumType, value, methodName);
    }

    /**
     * Returns the <code>Enum</code> of type <code>enumType</code> whose  
     * public method <code>methodName</code> return is 
     * equal to <code>value</code>.<br/>
     *
     * @param enumType
     * @param value
     * @param methodName
     * @return
     */
    public static <E extends Enum<E>> E from(Class<E> enumType, Object value, String methodName) {
        EnumSet<E> enumSet = EnumSet.allOf(enumType);
        for (E en : enumSet) {
            try {
                String invoke = enumType.getMethod(methodName).invoke(en).toString();
                if (invoke.equals(value.toString())) {
                    return en;
                }
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }

    private static String getMethodIdentifier(Class<?> enumType) {
        Method[] methods = enumType.getDeclaredMethods();
        String name = null;
        for (Method method : methods) {
            int mod = method.getModifiers();
            if (Modifier.isPublic(mod) && !Modifier.isStatic(mod) && !Modifier.isFinal(mod)) {
                name = method.getName();
                break;
            }
        }
        return name;
    }
}

Exemplo:

public enum Foo {
    ONE("eins"), TWO("zwei"), THREE("drei");

    private String value;

    private Foo(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

EnumUtil.from(Foo.class, "drei") retornos Foo.THREE, porque ele vai usar getValue para corresponder "Drei", que é público único, não final e método estático não em Foo. No caso Foo tem mais do que na pública, não é final e não estática método, por exemplo, getTranslate que retorna "Drei", o outro método pode ser usado:. EnumUtil.from(Foo.class, "drei", "getTranslate")

Como switch versão ainda não foi mencionado eu introduzi-lo (reutilizando enum do OP):

  private enum Blah {
    A, B, C, D;

    public static Blah byName(String name) {
      switch (name) {
        case "A":
          return A;
        case "B":
          return B;
        case "C":
          return C;
        case "D":
          return D;
        default:
          throw new IllegalArgumentException(
            "No enum constant " + Blah.class.getCanonicalName() + "." + name);
      }
    }
  }

Uma vez que este não dão qualquer valor adicional para o método valueOf(String name), ela só faz sentido definir um método adicional, se queremos ter um comportamento diferente. Se não quiser levantar uma IllegalArgumentException podemos alterar a implementação de:

  private enum Blah {
    A, B, C, D;

    public static Blah valueOfOrDefault(String name, Blah defaultValue) {
      switch (name) {
        case "A":
          return A;
        case "B":
          return B;
        case "C":
          return C;
        case "D":
          return D;
        default:
          if (defaultValue == null) {
            throw new NullPointerException();
          }
          return defaultValue;
      }
    }
  }

Ao fornecer um valor padrão mantemos o contrato de Enum.valueOf(String name) sem lançar uma IllegalArgumentException dessa maneira que em nenhum caso null é retornado. Portanto, jogar um NullPointerException se o nome for null e em caso de default se defaultValue é null. É assim que funciona valueOfOrDefault.

Esta abordagem adota o projeto do Map-Interface que fornece uma Map.getOrDefault(Object key, V defaultValue) método como de Java 8.

Eu gosto de usar esse tipo de processo para analisar comandos como strings em enumerações. I normalmente têm uma das enumerações como "desconhecido" por isso ajuda a ter que retornou quando os outros não são encontrados (mesmo em uma base caso insensível), em vez de nula (que significa não há nenhum valor). Daí eu usar essa abordagem.

static <E extends Enum<E>> Enum getEnumValue(String what, Class<E> enumClass) {
    Enum<E> unknown=null;
    for (Enum<E> enumVal: enumClass.getEnumConstants()) {  
        if (what.compareToIgnoreCase(enumVal.name()) == 0) {
            return enumVal;
        }
        if (enumVal.name().compareToIgnoreCase("unknown") == 0) {
            unknown=enumVal;
        }
    }  
    return unknown;
}

A maneira mais rápida para obter o nome de enum é criar um mapa de texto enum e valor quando do início da aplicação, e para obter o nome de chamar a função Blah.getEnumName ():

public enum Blah {
    A("text1"),
    B("text2"),
    C("text3"),
    D("text4");

    private String text;
    private HashMap<String, String> map;
    Blah(String text) {
    this.text = text;
    }

    public String getText() {
      return this.text;
    }

    static{
      createMapOfTextAndName();
    }

    public static void createMapOfTextAndName() {
        map = new HashMap<String, String>();
        for (Blah b : Blah.values()) {
             map.put(b.getText(),b.toString());
        }
    }
    public static String getEnumName(String text) {
        return map.get(text.toLowerCase());
    } 
}

Enum é muito útil, tenho vindo a utilizar Enum muito para adicionar uma descrição para alguns campos em diferentes idiomas, como o exemplo a seguir:

public enum Status {

    ACT(new String[] { "Accepted", "مقبول" }),
    REJ(new String[] { "Rejected", "مرفوض" }),
    PND(new String[] { "Pending", "في الانتظار" }),
    ERR(new String[] { "Error", "خطأ" }),
    SNT(new String[] { "Sent", "أرسلت" });

    private String[] status;

    public String getDescription(String lang) {
        return lang.equals("en") ? status[0] : status[1];
    }

    Status(String[] status) {
        this.status = status;
    }
}

E então você pode recuperar a descrição dinamicamente com base no código de linguagem passado para o método getDescription(String lang), por exemplo:

String statusDescription = Status.valueOf("ACT").getDescription("en");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top