it-swarm.com.de

Wie erhalte ich einen Enum-Wert aus einem String-Wert in Java?

Angenommen, ich habe eine Aufzählung, die gerecht ist

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

und ich möchte den enum-Wert eines Strings finden, zum Beispiel "A", der Blah.A sein würde. Wie wäre das möglich?

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

1848
Malachi

Ja, Blah.valueOf("A") gibt Ihnen _Blah.A_.

Beachten Sie, dass der Name eine genaue Übereinstimmung sein muss, einschließlich Groß-/Kleinschreibung: Blah.valueOf("a") und Blah.valueOf("A ") werfen beide ein IllegalArgumentException .

Die statischen Methoden valueOf() und values() werden zur Kompilierungszeit erstellt und erscheinen nicht im Quellcode. Sie erscheinen jedoch in Javadoc. Beispiel: Dialog.ModalityType zeigt beide Methoden an.

2123
Michael Myers

Eine andere Lösung, wenn der Text nicht mit dem Aufzählungswert übereinstimmt:

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;
    }
}
811
JoséMi

Hier ist ein nützliches Dienstprogramm, das ich verwende:

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

Dann habe ich in meiner Aufzählungsklasse normalerweise folgendes, um ein bisschen Tipparbeit zu sparen:

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

Wenn Ihre Aufzählungen keine Großbuchstaben sind, ändern Sie einfach die Zeile Enum.valueOf.

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

116
Geoffrey Zheng

Verwenden Sie das Muster von Joshua Bloch, Effektives 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 Map von Instanzen

Ausführungsreihenfolge von statischen Blöcken in einem Aufzählungstyp

Wie kann ich ein Java -Enum anhand seines Zeichenfolgenwerts nachschlagen?

77
Darrell Teague

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

edit
Geändert toUpperCase zu toUpperCase(Locale.ENGLISH) basierend auf tc. Comment und Java docs

edit2 Auf Android sollten Sie Locale.US als sulai points) verwenden out .

73
João Portela

Hier ist eine Methode, die dies für alle Enum-Typen ausführen kann und bei der die Groß- und Kleinschreibung nicht berücksichtigt wird.

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

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

33
Peter Lawrey

Wenn Sie kein eigenes Hilfsprogramm schreiben möchten, verwenden Sie die guava -Bibliothek von Google:

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

Im Gegensatz zur eingebauten Funktion Java können Sie damit prüfen, ob A in Blah vorhanden ist und keine Ausnahme auslöst.

27
Andrejs

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

Meine 2 Cent hier: Verwenden von Java8-Streams + Überprüfen einer genauen Zeichenfolge:

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 wurde in fromString() umbenannt, da sie nach dieser Konvention benannt wurde. Sie erhalten einige Vorteile aus der Sprache Java. zum Beispiel:

  1. Direkte Konvertierung von Typen in der HeaderParam-Annotation
23
Manu

Möglicherweise müssen Sie dazu:

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

Eine weitere Ergänzung:

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

Dies gibt Ihnen den Wert durch einen Stringified Enum Name zurück. Wenn Sie "PERSON" in fromEnumName angeben, wird der Wert von Enum zurückgegeben, d. h. "Person".

15

Eine andere Möglichkeit hierfür ist die implizite statische Methode name() von Enum. name gibt die genaue Zeichenfolge zurück, die zum Erstellen dieser Enumeration verwendet wurde, mit der gegen die angegebene Zeichenfolge geprüft werden kann:

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

Testen:

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

//it will print B  B

inspiration: 10 Beispiele für Enum in Java

11
Vikram

Lösung mit Guava-Bibliotheken. Bei der Methode getPlanet () wird die Groß- und Kleinschreibung nicht berücksichtigt, daher gibt getPlanet ("MerCUrY") 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();
   }
}
8
javabrew

In Java 8 ist das statische Kartenmuster noch einfacher und meine bevorzugte Methode. Wenn Sie das Enum mit Jackson verwenden möchten, können Sie toString überschreiben und dieses anstelle von name verwenden. Kommentieren Sie dann 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);
    }
}
7
Novaterata

Um die vorherigen Antworten zu ergänzen und einige der Diskussionen um Nullen und NPE anzusprechen, verwende ich Guava Optionals, um abwesende/ungültige Fälle zu behandeln. Dies funktioniert hervorragend für das Parsen von URIs und Parametern.

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 sich nicht bewusst sind, finden Sie hier weitere Informationen zum Vermeiden von Null mit Optional: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional

6
tom

O (1) -Methode, inspiriert von sparsam generiertem Code, der eine Hashmap verwendet.

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

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

Die commons-lang -Bibliothek von Apache hat eine statische Funktion org.Apache.commons.lang3.EnumUtils.getEnum , die Ihrem Enum-Typ einen String zuordnet. Die gleiche Antwort wie bei Geoffreys, aber warum solltest du deine eigene rollen, wenn es schon draußen in der Wildnis ist?.

4
pjklauser

Hinzufügen zu der bestbewerteten Antwort mit einem hilfreichen Hilfsprogramm ...

valueOf() löst zwei verschiedene Ausnahmen aus, wenn die Eingabe nicht gefällt.

  • IllegalArgumentException
  • NullPointerExeption

Wenn Ihre Anforderungen so sind, dass Sie keine Garantie dafür haben, dass Ihr String definitiv mit einem Enum-Wert übereinstimmt, z. B. wenn die String-Daten aus einer Datenbank stammen und eine alte Version des Enums enthalten könnten, müssen Sie diese behandeln häufig...

Hier ist eine wiederverwendbare Methode, die es uns ermöglicht, eine Standard-Enum zu definieren, die zurückgegeben wird, wenn der übergebene String nicht übereinstimmt.

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

Benutze es so:

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
}
4
lance.dolan

Java.lang.Enum definiert mehrere nützliche Methoden, die für alle Aufzählungstypen in Java verfügbar sind:

  • Sie können die Methode name() verwenden, um den Namen aller Enum-Konstanten abzurufen. String-Literal, das zum Schreiben von Enum-Konstanten verwendet wird, ist deren Name.
  • In ähnlicher Weise kann die Methode values() verwendet werden, um ein Array aller Enum-Konstanten von einem Enum-Typ abzurufen.
  • Und für die gestellte Frage können Sie die Methode valueOf() verwenden, um einen beliebigen String in eine Enum-Konstante in Java zu konvertieren, wie unten gezeigt.
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-Snippet gibt die valueOf() -Methode eine Enum-Konstante Gender.MALE zurück und ruft den Namen auf, der "MALE" zurückgibt.

3
KNU

Wie wäre es mit?

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

Enum ist sehr nützlich, ich habe Enum häufig verwendet, um eine Beschreibung für einige Felder in verschiedenen Sprachen hinzuzufügen, wie im folgenden 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;
    }
}

Anschließend können Sie die Beschreibung dynamisch anhand des Sprachcodes abrufen, der an die Methode getDescription(String lang) übergeben wurde. Beispiel:

String statusDescription = Status.valueOf("ACT").getDescription("en");
2

Da eine switch -Version noch nicht erwähnt wurde, führe ich sie ein (Wiederverwendung der OP-Aufzählung):

  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 dies der Methode valueOf(String name) keinen zusätzlichen Wert gibt, ist es nur sinnvoll, eine zusätzliche Methode zu definieren, wenn wir ein anderes Verhalten wünschen. Wenn wir kein IllegalArgumentException auslösen möchten, können wir die Implementierung folgendermaßen ä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;
      }
    }
  }

Indem wir einen Standardwert angeben, behalten wir das Vertrag von Enum.valueOf(String name) bei, ohne IllegalArgumentException in der Weise zu werfen, dass in keinem Fall null zurückgegeben wird. Deshalb werfen wir ein NullPointerException, wenn der Name null ist, und im Falle von default, wenn defaultValuenull ist. So funktioniert valueOfOrDefault.

Dieser Ansatz übernimmt das Design der Map- Schnittstelle, die eine Methode Map.getOrDefault(Object key, V defaultValue) ab Java 8 bereitstellt.

2
LuCio

Ein weiteres Dienstprogramm, das auf umgekehrte Weise erfasst. Verwenden Sie einen Wert, der diese Enum nicht anhand des Namens identifiziert.

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") gibt Foo.THREE zurück, da es getValue verwendet, um "drei" zu finden, eine eindeutige öffentliche, nicht endgültige und nicht statische Methode in Foo. Falls Foo über mehr als eine öffentliche, nicht endgültige und nicht statische Methode verfügt, z. B. getTranslate, die "drei" zurückgibt, kann die andere Methode verwendet werden: EnumUtil.from(Foo.class, "drei", "getTranslate").

1
Moesio

Ich verwende diese Art von Verfahren gerne, um Befehle als Zeichenfolgen in Aufzählungen zu analysieren. Normalerweise habe ich eine der Aufzählungen als "unbekannt", daher ist es hilfreich, wenn diese zurückgegeben wird, wenn die anderen nicht gefunden werden (auch wenn die Groß- und Kleinschreibung nicht beachtet wird) und nicht null (das heißt, es gibt keinen Wert). Daher benutze 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;
}
0
John Hemming

Am schnellsten können Sie den Namen von enum ermitteln, indem Sie beim Start der Anwendung eine Zuordnung von enum-Text und -Wert erstellen und 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());
    } 
}
0
Bishal Jaiswal