write - java how to define enum




Suchen Sie Java-Enumeration nach Zeichenfolgenwert (16)

Sag, ich habe ein enum, das gerecht ist

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

und ich würde gerne den Enum-Wert einer Saite finden, zum Beispiel "A" was Blah.A . 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 verwenden?


Am besten ist es, Blah.valueOf(string) aber Sie können auch Enum.valueOf(Blah.class, string) .


Benutze das Muster von Joshua Bloch, Effektives Java :

(vereinfacht für die Kürze)

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 of instances

Ausführungsreihenfolge der statischen Blöcke in einem Enum-Typ

Wie kann ich eine Java-Enumeration anhand ihres String-Werts suchen?


Ein anderes Dienstprogramm, das auf umgekehrte Weise aufnimmt. Verwenden eines Werts, der diese Enum identifiziert, nicht anhand seines Namens.

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 , weil getValue , um "drei" zu finden, was eine eindeutige öffentliche, nicht endgültige und nicht statische Methode in Foo ist. Für den Fall, dass Foo mehr hat als public, nicht final und nicht statisch, zum Beispiel getTranslate das "drei" zurückgibt, kann die andere Methode verwendet werden: EnumUtil.from(Foo.class, "drei", "getTranslate") .


Eine andere Lösung, wenn der Text nicht identisch mit dem 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 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;
}

In meiner Enum-Klasse habe ich das normalerweise, um ein wenig Tipparbeit zu sparen:

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

Wenn Ihre Enums keine Großbuchstaben sind, ändern Sie Enum.valueOf Zeile Enum.valueOf .

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


Hier ist eine Methode, die es für jede Enum machen kann, und die Groß- und Kleinschreibung nicht beachtet.

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

Ich verwende diese Art von Prozess gerne, um Befehle als Strings in Aufzählungen zu parsen. Normalerweise habe ich eine der Aufzählungen als "unbekannt", so dass es hilfreich ist, wenn die anderen nicht gefunden werden (selbst wenn die Groß- und Kleinschreibung nicht beachtet wird) und nicht null (dh 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;
}

In Java 8 ist das statische Map-Muster noch einfacher und ist meine bevorzugte Methode. Wenn Sie die Enum mit Jackson verwenden möchten, können Sie toString überschreiben und diesen anstelle von name verwenden und dann mit @JsonValue annotieren

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

Ja, Blah.valueOf("A") wird dir Blah.A .

Beachten Sie, dass der Name exakt übereinstimmen muss, einschließlich case: Blah.valueOf("a") und Blah.valueOf("A ") werfen beide eine IllegalArgumentException .

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


Lösung mit Guava-Bibliotheken. Bei der Methode getPlanet () wird die Groß- / Kleinschreibung nicht beachtet, 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();
   }
}

Meine 2 Cent hier: mit Java8 Streams + eine genaue Zeichenfolge überprüfen:

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

** BEARBEITEN **

Die Funktion wurde in fromString() seit sie mit dieser Konvention benannt wurde. Sie profitieren von der Java-Sprache selbst. beispielsweise:

  1. Direkte Konvertierung von Typen bei HeaderParam Annotation

O (1) -Methode, die von einem durch Sparsamkeit erzeugten Code inspiriert wurde, der eine Hash-Map 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;
        }

}

Um zu den vorherigen Antworten hinzuzufügen und einige der Diskussionen über NULL und NPE anzugehen, verwende ich Guava-Optionen, um fehlende / ungültige Fälle zu behandeln. Dies funktioniert hervorragend 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 dies nicht wissen, finden Sie hier weitere Informationen zum Vermeiden von null mit Optional: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional


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

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

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


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

  • Sie können die name() -Methode verwenden, um den Namen aller Enum-Konstanten zu erhalten. String-Literal zum Schreiben von Enum-Konstanten ist ihr Name.
  • In ähnlicher Weise kann die values() -Methode verwendet werden, um ein Array aller Enum-Konstanten von einem Enum-Typ zu erhalten.
  • Und für die gestellte Frage können Sie die valueOf() -Methode verwenden, um einen beliebigen String in 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 Codefragment gibt die valueOf() -Methode eine Enum-Konstante Gender.MALE zurück, wobei der aufrufende Name "MALE" zurückgibt.


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






enums