Hoe krijg ik een opsommingswaarde van een tekenreekswaarde in Java?

Stel dat ik een opsomming heb die gewoon

. is

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

en ik zou graag de enumwaarde van een string willen vinden, bijvoorbeeld "A"wat Blah.Azou zijn. Hoe zou het mogelijk zijn om dit te doen?

Is de Enum.valueOf()de methode die ik nodig heb? Zo ja, hoe zou ik dit dan gebruiken?


Antwoord 1, autoriteit 100%

Ja, Blah.valueOf("A")geeft je Blah.A.

Merk op dat de naam een ​​exacteovereenkomst moet zijn, inclusief hoofdletters: Blah.valueOf("A")en Blah.valueOf("A ")gooien allebei een IllegalArgumentException.

De statische methoden valueOf()en values()worden gemaakt tijdens het compileren en verschijnen niet in de broncode. Ze verschijnen echter wel in Javadoc; bijvoorbeeld Dialog.ModalityTypetoont beide methoden.


Antwoord 2, autoriteit 39%

Een andere oplossing als de tekst niet hetzelfde is als de opsommingswaarde:

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

Antwoord 3, autoriteit 5%

Gebruik het patroon van Joshua Bloch, Effective Java:

(vereenvoudigd voor de beknoptheid)

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().toLowerCase(),instance);
        }
        ENUM_MAP = Collections.unmodifiableMap(map);
    }
    public static MyEnum get (String name) {
        return ENUM_MAP.get(name.toLowerCase());
    }
}

Zie ook:

Oracle Java-voorbeeld met Enum en Map of instanties

Uitvoeringsvolgorde van van statische blokken in een Enum-type

Hoe kan ik een Java-enum opzoeken van de tekenreekswaarde


Antwoord 4, autoriteit 5%

Hier is een handig hulpprogramma dat ik gebruik:

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

In mijn enum-klas heb ik meestal dit om wat typen te besparen:

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

Als je opsommingen niet allemaal hoofdletters zijn, verander dan gewoon de regel Enum.valueOf.

Jammer dat ik T.classniet kan gebruiken voor Enum.valueOfomdat Twordt gewist.


Antwoord 5, autoriteit 3%

Je moet ook voorzichtig zijn met je zaak. Laat me het uitleggen: Blah.valueOf("A")doen werkt, maar Blah.valueOf("A")zal niet werken. Dan zou Blah.valueOf("a".toUpperCase(Locale.ENGLISH))weer werken.

bewerken
toUpperCasegewijzigd in toUpperCase(Locale.ENGLISH)op basis van tc. commentaaren de java-documenten

edit2
Op Android moet u Locale.US, zoals sulai aangeeft.


Antwoord 6, autoriteit 2%

In Java 8 of hoger, met behulp van 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();
    }
}

Antwoord 7, autoriteit 2%

Hier is een methode die het voor elke Enum kan doen, en is niet hoofdlettergevoelig.

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

Antwoord 8

Het gebruik van Blah.valueOf(string)is het beste, maar u kunt ook Enum.valueOf(Blah.class, string)gebruiken.


Antwoord 9

Mijn 2 cent hier: Java8 Streams gebruiken + een exacte tekenreeks controleren:

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

** BEWERKEN **

De functie hernoemd naar fromString()sinds je hem een ​​naam geeft volgens die conventie, je zult enkele voordelen halen uit de Java-taal zelf; bijvoorbeeld:

  1. Directe conversie van typen bij HeaderParam-annotatie

Antwoord 10

Als je niet je eigen hulpprogramma wilt schrijven, gebruik dan bibliotheek:

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

In tegenstelling tot de ingebouwde Java-functie kunt u hiermee controleren of A aanwezig is in Blah en geen uitzondering genereren.


Antwoord 11

Mogelijk heb je dit nodig:

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

Nog een toevoeging:

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

Hiermee krijgt u de waarde terug met een Stringified Enum Name For b.v. als u “PERSON” opgeeft in de fromEnumName, krijgt u de waarde van Enum terug, d.w.z. “Persoon”


Antwoord 12

Een andere manier om dit te doen is door de impliciete statische methode name()van Enum te gebruiken. name geeft de exacte tekenreeks terug die is gebruikt om die enum te maken die kan worden gebruikt om te controleren aan de hand van de opgegeven tekenreeks:

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

inspiratie: 10 voorbeelden van Enum in Java


Antwoord 13

Oplossing met Guava-bibliotheken. Methode getPlanet () is niet hoofdlettergevoelig, dus
getPlanet (“MerCUrY”) zal Planet.MERCURY teruggeven.

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

Antwoord 14

In Java 8 is het statische kaartpatroon nog eenvoudiger en mijn voorkeursmethode. Als je de Enum met Jackson wilt gebruiken, kun je toString overschrijven en die gebruiken in plaats van naam, en vervolgens annoteren met @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);
    }
}

Antwoord 15

Om aan de vorige antwoorden toe te voegen en enkele van de discussies rond nulls en NPE aan te pakken, gebruik ik Guava optionals om afwezige/ongeldige gevallen af ​​te handelen. Dit werkt uitstekend voor het ontleden van URI/parameter.

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

Voor degenen die het niet weten, hier is wat meer informatie over het vermijden van null met Optioneel: https:// code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optioneel


Antwoord 16

Enum is erg handig, ik heb Enumveel gebruikt om een ​​beschrijving toe te voegen voor sommige velden in verschillende talen, zoals het volgende voorbeeld:

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

En dan kunt u de beschrijving dynamisch ophalen op basis van de taalcode die is doorgegeven aan de methode getDescription(String lang), bijvoorbeeld:

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

Antwoord 17

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

Antwoord 18

O(1)-methode geïnspireerd op door zuinigheid gegenereerde code die een hashmap gebruikt.

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

Antwoord 19

Apache’s commons-langbibliotheek heeft een statische functie org.apache.commons.lang3.EnumUtils.getEnumdie een string toewijst aan uw Enum-type. Hetzelfde antwoord in wezen als Geoffreys, maar waarom zou je er zelf een rollen als het al in het wild is.


Antwoord 20

Hoe zit het met?

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

Antwoord 21

java.lang.Enumdefinieert verschillende nuttige methoden, die beschikbaar zijn voor alle opsommingstypen in Java:

  • U kunt de methode name()gebruiken om de naam van alle Enum-constanten te krijgen. Letterlijke tekenreeks die wordt gebruikt om enum-constanten te schrijven, is hun naam.
  • Op dezelfde manier kan de methode values()worden gebruikt om een ​​array van alle Enum-constanten van een Enum-type te krijgen.
  • En voor de gestelde vraag kun je de methode valueOf()gebruiken om elke String naar Enum-constante in Java te converteren, zoals hieronder weergegeven.
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 dit codefragment retourneert de methode valueOf()een Enum-constante Gender.MALE, waarbij de naam wordt aangeroepen die "MALE"retourneert.


Antwoord 22

Toevoegen aan het best beoordeelde antwoord, met een handig hulpprogramma…

valueOf()genereert twee verschillende Exceptions in gevallen waarin het de invoer niet leuk vindt.

  • IllegalArgumentException
  • NullPointerExeption

Als uw vereisten zodanig zijn dat u geen enkele garantie hebt dat uw String zeker overeenkomt met een enum-waarde, bijvoorbeeld als de String-gegevens uit een database komen en een oude versie van de enum kunnen bevatten, dan hebt u om deze vaak te behandelen…

Dus hier is een herbruikbare methode die ik heb geschreven waarmee we een standaard Enum kunnen definiëren die moet worden geretourneerd als de string die we doorgeven niet overeenkomt.

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

Gebruik het als volgt:

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
}

Antwoord 23

Omdat een switch-versie nog niet is genoemd, introduceer ik deze (hergebruik de opsomming van 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);
      }
    }
  }

Aangezien dit geen extra waarde geeft aan de methode valueOf(String name), heeft het alleen zin om een ​​extra methode te definiëren als we een ander gedrag willen hebben. Als we geen IllegalArgumentExceptionwillen verhogen, kunnen we de implementatie wijzigen in:

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

Door een standaardwaarde op te geven, behouden we de contractvan Enum.valueOf(String name)zonder een IllegalArgumentExceptionte gooien op die manier die in geen geval nullwordt geretourneerd. Daarom gooien we een NullPointerExceptionals de naam nullis en in het geval van defaultals defaultValuenull. Zo werkt valueOfOrDefault.

Deze benadering neemt het ontwerp van de Map-interface over, die een methode Map.getOrDefault(Object key, V defaultValue)biedt vanaf Java 8.


Antwoord 24

Ik was op zoek naar een antwoord om de naam “blah” te vinden en niet de waarde ervan (niet de tekst). baseren op @Manu (@Mano)antwoord Ik vind deze code nuttig:

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 valueOfCode(String blahCode) throws IllegalArgumentException {
    Blah blah = Arrays.stream(Blah.values())
            .filter(val -> val.name().equals(blahCode))
            .findFirst()
            .orElseThrow(() -> new IllegalArgumentException("Unable to resolve blah : " + blahCode));
    return blah;
}

}


Antwoord 25

Nog een hulpprogramma dat op omgekeerde wijze vastlegt. Een waarde gebruiken die die Enum identificeert, niet van zijn naam.

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

Voorbeeld:

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")retourneert Foo.THREE, omdat het getValuezal gebruiken om te matchen met “drei “, wat een unieke openbare, niet definitieve en niet statische methode is in Foo.
Als Foo meer dan een openbare, geen definitieve en niet-statische methode heeft, bijvoorbeeld getTranslatedie “drei” retourneert, kan de andere methode worden gebruikt: EnumUtil.from(Foo.class, "drei", "getTranslate").


Antwoord 26

Enum waardeOf()
Een enum-klasse krijgt automatisch een statische methode valueOf() in de klasse wanneer deze wordt gecompileerd. De methode valueOf() kan worden gebruikt om een ​​instantie van de enum-klasse te verkrijgen voor een gegeven String-waarde.
Bijvoorbeeld: –

public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println(Strings.TWO.name());
    }
    enum Strings {
        ONE, TWO, THREE
    }
}

Antwoord 27

Ik gebruik dit soort processen graag om commando’s als strings in opsommingen te ontleden. Ik heb normaal gesproken een van de opsommingen als “onbekend”, dus het helpt om die terug te geven wanneer de anderen niet worden gevonden (zelfs niet hoofdlettergevoelig) in plaats van null (dat betekent dat er geen waarde is). Daarom gebruik ik deze aanpak.

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

Antwoord 28

Kotlin-oplossing

Maak een extensie en roep vervolgens valueOf<MyEnum>("value")aan. Als het type ongeldig is, krijg je null en moet je het afhandelen

inline fun <reified T : Enum<T>> valueOf(type: String): T? {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        null
    }
}

U kunt ook een standaardwaarde instellen door valueOf<MyEnum>("value", MyEnum.FALLBACK)aan te roepen en een null-antwoord te vermijden. U kunt uw specifieke opsomming uitbreiden zodat de standaard automatisch is

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        default
    }
}

Of als je beide wilt, maak dan de tweede:

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default

Antwoord 29

De snelste manier om de naam van enum te krijgen, is door een kaart te maken van de tekst en waarde van enum wanneer de toepassing start, en om de naam te krijgen, roept u de functie 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.name());
        }
    }
    public static String getEnumName(String text) {
        return map.get(text.toLowerCase());
    } 
}

Antwoord 30

Blah.valueOf("A")is de verklaring die u zoekt, maar houd er rekening mee dat dit HOOFDVALGEVOELIGHEIDis, dus Blah.valueOf(“a “) zal niet werken en zal een Uitzondering genereren.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

1 × two =

Other episodes