Frage

Sagen, ich habe eine Enumeration, die gerade ist

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

und ich möchte den ENUM-Wert einer Zeichenfolge finden, zum Beispiel "A" die Blah.A würde. Wie wäre es möglich, dies zu tun?

Ist die Enum.valueOf() die Methode, die ich brauche? Wenn ja, wie würde ich das?

War es hilfreich?

Lösung

Ja, Blah.valueOf("A") geben Ihnen Blah.A.

Beachten Sie, dass der Name muss eine sein, genau Spiel, einschließlich Fall. Blah.valueOf("a") und Blah.valueOf("A ") sowohl ein IllegalArgumentException werfen

Die statischen Methoden valueOf() und values() werden bei der Kompilierung erstellt und erscheinen nicht im Quellcode. Sie erscheinen in Javadoc, obwohl; beispielsweise Dialog.ModalityType zeigt beide Methoden .

Andere Tipps

Eine andere Lösung, wenn der Text nicht gleich auf den Aufzählungswert ist:

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

Hier ist ein raffiniertes Dienstprogramm, das ich verwenden:

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

Da ist in meiner Enum Klasse Ich habe dies in der Regel etwas Tipp zu speichern:

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

Wenn Ihre Aufzählungen sind nicht alle Kappen, sondern nur die Enum.valueOf Linie ändern.

Schade, dass ich nicht T.class für Enum.valueOf verwenden als T gelöscht wird.

Sie sollten auch mit Ihrem Fall vorsichtig sein. Lassen Sie mich erklären: Blah.valueOf("A") Werke zu tun, aber Blah.valueOf("a") wird nicht funktionieren. Dann wieder Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) funktionieren würde.

Bearbeiten
Veränderte toUpperCase toUpperCase(Locale.ENGLISH) auf tc basiert. Kommentar und die java docs

edit2 Auf Android sollten Sie Locale.US , wie sulai weist darauf hin, .

Mit dem Muster von Joshua Bloch, Effective Java :

(der Kürze halber vereinfacht)

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

Siehe auch:

Oracle Java Beispiel mit Enum und Karte von Instanzen

Ausführungsreihenfolge von von statischen Blöcken in einem Enum-Typ

Wie kann ich Lookup eine Java-Enumeration von seinem String-Wert

Hier ist eine Methode, die es für jedes Enum tun kann, und ist Groß- und Kleinschreibung.

/** 
 * 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()
    ));
}

Blah.valueOf(string) Verwendung ist am besten, aber Sie können auch verwenden Enum.valueOf(Blah.class, string).

Wenn Sie nicht möchten, dass Ihr eigenes Programm schreiben Google verwenden Bibliothek:

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

Im Gegensatz zu dem in Java-Funktion eingebaut es läßt Du überprüfen, ob A in Blah ist und keine Ausnahme werfen.

Meine 2 Cent hier: mit Java8 Streams + eine exakte Zeichenfolge Überprüfung:

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

die Funktion Umbenannt es fromString() seit Namensgebung dieser Konvention verwendet, werden Sie einige Vorteile von Java-Sprache selbst zu erhalten; zum Beispiel:

  1. direkte Umwandlung von Typ bei HeaderParam Anmerkung

In Java 8 oder höher, mit 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();
    }
}

Sie können dazu brauchen:

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 Addition:

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

Diese kehren Sie den Wert von einem Zeichenfolge Enum-Namen für z.B. wenn Sie „Person“ in der fromEnumName bieten werde es zurückgeben Sie den Wert Enum heißt „Person“

Eine andere Möglichkeit, dies zu tun, durch implizite statische Methode name() von Enum verwenden. Name wird exakt die gleiche Zeichenkette verwendet zurückgeben, dass Enum zu erzeugen, die verwendet werden können, gegen vorgesehen Zeichenfolge zu überprüfen:

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

Test:

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

//it will print B  B

Inspiration: 10 Beispiele für Enum in Java

Lösung mit Guava Bibliotheken. Verfahren getPlanet () ist unempfindlich Fall, so getPlanet ( "Mercury") wird Planet.MERCURY zurück.

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

zu den vorherigen Antworten hinzuzufügen, und adressieren einige der Diskussionen um Nullen und NPE Ich bin mit Guava Optionals abwesend / ungültigen Fälle zu behandeln. Dies funktioniert gut für URI / Parameter-Parsing.

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

Für diejenigen, die nicht bewusst, hier einige weitere Informationen zur Vermeidung von null mit Optional: https: // code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional

In Java 8 das statische Karte Muster ist noch einfacher und ist meine preffered Methode. Wenn Sie die Enum mit Jackson verwenden möchten, können Sie überschreiben toString und verwenden, die anstelle des Namens, der dann mit Anmerkungen versehen mit @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) Methode aus Sparsamkeit inspiriert generierten Code, der eine hashmap verwenden.

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 definiert mehrere nützliche Methoden, die für alle Aufzählungstyp in Java zur Verfügung:

  • Sie können name() Methode Namen aller Enum-Konstanten zu erhalten. Stringliteral verwendet, um Aufzählungskonstanten ihren Namen zu schreiben.
  • ähnlich values() Verfahren verwendet werden können, ein Array aller Enum-Konstanten von einem Enum-Typ zu erhalten.
  • Und für die gestellte Frage, können Sie valueOf() Methode zu konvertieren jeden String ENUM Konstante in Java, wie unten gezeigt.
  • verwenden
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

In diesem Code-Schnipsel, valueOf() Methode liefert eine Enum Konstante Gender.MALE, Namen ruft auf, dass "MALE" zurück.

Apache commons-lang Bibliothek verfügt über eine statische Funktion org.apache.commons.lang3.EnumUtils.getEnum , die einen String auf Ihre Enum-Typ abbildet. Gleiche Antwort im Wesentlichen als Geoffreys aber warum Ihre eigene Rolle, wenn es bereits in der freien Natur da draußen ist.

Hinzufügen auf die am besten bewertete Antwort, mit einem hilfreichen Werkzeug ...

valueOf() wirft zwei verschiedene Ausnahmen in Fällen, in denen es nicht seine Eingabe nicht mag.

  • IllegalArgumentException
  • NullPointerExeption

Wenn Ihre Anforderungen sind, so dass Sie haben keine Garantie, dass Ihr String wird auf jeden Fall einen Enum-Wert entspricht, zum Beispiel, wenn die String-Daten aus einer Datenbank kommen und alte Version des Enum enthalten könnten, dann werden Sie brauchen zu handhaben diese oft ...

Hier ist also ein wiederverwendbares Methode, die ich schrieb, die uns ein Standard-Enum definieren können zurückgegeben werden, wenn der String wir nicht übereinstimmen übergeben.

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

Verwenden Sie es wie folgt aus:

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
}

Was?

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

Ein weiterer Nutzen in umgekehrter Weise zu erfassen. Mit einem Wert, der erkennt, dass Enum, nicht von seinem Namen.

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

Beispiel:

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") kehrt Foo.THREE, weil es getValue verwenden „drei“ gefunden, die einzigartige öffentlich ist, nicht endgültig und kann nicht statische Methode in Foo. Im Fall, dass Foo mehr als auf öffentliche, nicht endgültig und kann nicht statische Methode zum Beispiel getTranslate die „drei“ zurückgibt, kann das andere Verfahren verwendet werden. EnumUtil.from(Foo.class, "drei", "getTranslate")

Als switch-Version noch nicht erwähnt worden stelle ich es (OP ENUM Wiederverwendung):

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

Da diese geben keinen zusätzlichen Wert auf die valueOf(String name) Methode, macht es nur Sinn eine zusätzliche Methode zu definieren, wenn wir ein anderes Verhalten haben wollen. Wenn wir nicht eine IllegalArgumentException erhöhen wollen wir die Umsetzung ändern:

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

einen Standardwert Indem wir halten Sie die Vertrag von Enum.valueOf(String name) ohne eine IllegalArgumentException auf diese Weise zu werfen, dass in keinem Fall null zurückgegeben. Daher werfen wir einen NullPointerException, wenn der Name null und bei default ist, wenn defaultValue null ist. Das ist, wie valueOfOrDefault funktioniert.

Dieser Ansatz nimmt das Design des Map-Interface, die 8 ein Verfahren Map.getOrDefault(Object key, V defaultValue) wie von Java zur Verfügung stellt.

Ich mag diese Art von Verfahren verwenden, um Befehle als Strings in Aufzählungen zu analysieren. Ich habe normalerweise eine der Aufzählungen als „unbekannt“ so ist es, dass zurückgegeben zu haben, hilft, wenn die andere nicht (auch nicht auf Groß- und Kleinschreibung Basis) gefunden und nicht null (dh Bedeutung kein Wert ist). Daher verwende ich diesen Ansatz.

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

Der schnellste Weg, den Namen Enum zu erhalten, ist eine Karte von Enum Text und Wert, wenn der Start der Anwendung zu erstellen, und der Name erhalten die Funktion Blah.getEnumName () aufrufen:

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 ist sehr nützlich, habe ich eine Beschreibung für einige Felder in verschiedenen Sprachen viel mit Enum hinzuzufügen, wie das folgende Beispiel:

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

Und dann können Sie sich die Beschreibung dynamisch in den Sprachcode basiert abrufen Methode übergeben getDescription(String lang), zum Beispiel:

String statusDescription = Status.valueOf("ACT").getDescription("en");
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top