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.A
zou 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.ModalityType
toont 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.class
niet kan gebruiken voor Enum.valueOf
omdat T
wordt 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
toUpperCase
gewijzigd 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:
Antwoord 10
Als je niet je eigen hulpprogramma wilt schrijven, gebruik dan guavebibliotheek:
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 Enum
veel 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.Enum
definieert 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 IllegalArgumentException
willen 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 IllegalArgumentException
te gooien op die manier die in geen geval null
wordt geretourneerd. Daarom gooien we een NullPointerException
als de naam null
is en in het geval van default
als defaultValue
null
. 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 getValue
zal 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 getTranslate
die “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.