Frage

Ich möchte eine Enumeration von seinem String-Wert nachzuschlagen (oder möglicherweise einen anderen Wert). Ich habe den folgenden Code versucht, aber es erlaubt nicht statisch in initialisers. Gibt es eine einfache Art und Weise?

public enum Verbosity {

    BRIEF, NORMAL, FULL;

    private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>();

    private Verbosity() {
        stringMap.put(this.toString(), this);
    }

    public static Verbosity getVerbosity(String key) {
        return stringMap.get(key);
    }
};
War es hilfreich?

Lösung

Mit der valueOf Methode, die automatisch für jeden Enum erstellt wird.

Verbosity.valueOf("BRIEF") == Verbosity.BRIEF

Für beliebige Werte beginnen mit:

public static Verbosity findByAbbr(String abbr){
    for(Verbosity v : values()){
        if( v.abbr().equals(abbr)){
            return v;
        }
    }
    return null;
}

Erst später verschieben auf Implementierung Karte, wenn Ihr Profiler sagt Ihnen zu.

Ich weiß, es Iterieren über alle Werte, aber mit nur 3 ENUM-Wert ist es kaum wert andere Anstrengung, in der Tat, es sei denn Sie viele Werte haben würde ich nicht mit einer Karte der Mühe wird es schnell genug sein.

Andere Tipps

Sie sind in der Nähe. Für beliebige Werte, versuchen, etwas wie folgt aus:

public enum Day { 

    MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
    THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;

    private final String abbreviation;

    // Reverse-lookup map for getting a day from an abbreviation
    private static final Map<String, Day> lookup = new HashMap<String, Day>();

    static {
        for (Day d : Day.values()) {
            lookup.put(d.getAbbreviation(), d);
        }
    }

    private Day(String abbreviation) {
        this.abbreviation = abbreviation;
    }

    public String getAbbreviation() {
        return abbreviation;
    }

    public static Day get(String abbreviation) {
        return lookup.get(abbreviation);
    }
}

mit Java 8 Sie mit dieser Art und Weise erreichen können:

public static Verbosity findByAbbr(final String abbr){
    return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}

@ Lyle Antwort ziemlich gefährlich ist, und ich habe es nicht besonders zu sehen, wenn Sie das Enum eine statische innere Klasse. Stattdessen habe ich so etwas wie diese verwendet, die die BootstrapSingleton Karten vor den Aufzählungen geladen werden.

Bearbeiten sollte dies kein Problem mehr mit modernen JVMs (JVM 1.6 oder höher) sein, aber ich denke, dass es mit JRebel noch Fragen sind, aber ich habe nicht die Chance hat, Retest es .

Laden Sie mich zuerst:

   public final class BootstrapSingleton {

        // Reverse-lookup map for getting a day from an abbreviation
        public static final Map<String, Day> lookup = new HashMap<String, Day>();
   }

Nun ist es in dem ENUM-Konstruktor laden:

   public enum Day { 
        MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
        THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;

        private final String abbreviation;

        private Day(String abbreviation) {
            this.abbreviation = abbreviation;
            BootstrapSingleton.lookup.put(abbreviation, this);
        }

        public String getAbbreviation() {
            return abbreviation;
        }

        public static Day get(String abbreviation) {
            return lookup.get(abbreviation);
        }
    }

Wenn Sie eine innere Enum können Sie einfach die Karte über dem Enumerationsdefinition definieren und dass (in der Theorie) soll vor geladen werden.

Und Sie können nicht verwenden valueOf () ?

Edit:. Btw, es gibt nichts, was man von der Verwendung statischer {} in einer Enum stoppen

In der Java Language Specification 7 gibt es eine ein Beispiel ! das spiegelt Ihre Frage auf der Initialisierung der Karte mit Selbstverweisen.

Falls es hilft anderen, die Option, die ich lieber, die hier nicht aufgeführt ist, verwendet Guava der Karten-Funktionalität :

public enum Vebosity {
    BRIEF("BRIEF"),
    NORMAL("NORMAL"),
    FULL("FULL");

    private String value;
    private Verbosity(final String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

    private static ImmutableMap<String, Verbosity> reverseLookup = 
            Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue);

    public static Verbosity fromString(final String id) {
        return reverseLookup.getOrDefault(id, NORMAL);
    }
}

Mit der Standard Sie null verwenden können, können Sie throw IllegalArgumentException oder Ihre fromString könnte eine Optional zurückkehren, was auch immer Verhalten, das Sie bevorzugen.

Vielleicht, werfen Sie einen Blick auf diese. Seine Arbeit für mich. Der Zweck ist, ‚RED‘ mit ‚/ red_color‘ nachzuschlagen. Deklarieren einer static map und Laden der enums in nur einmal einige Leistungsvorteile mit sich bringen würde, wenn die enums viele.

public class Mapper {

public enum Maps {

    COLOR_RED("/red_color", "RED");

    private final String code;
    private final String description;
    private static Map<String, String> mMap;

    private Maps(String code, String description) {
        this.code = code;
        this.description = description;
    }

    public String getCode() {
        return name();
    }

    public String getDescription() {
        return description;
    }

    public String getName() {
        return name();
    }

    public static String getColorName(String uri) {
        if (mMap == null) {
            initializeMapping();
        }
        if (mMap.containsKey(uri)) {
            return mMap.get(uri);
        }
        return null;
    }

    private static void initializeMapping() {
        mMap = new HashMap<String, String>();
        for (Maps s : Maps.values()) {
            mMap.put(s.code, s.description);
        }
    }
}
}

Bitte setzen in Ihrem opinons.

Sie können Ihre Enum wie folgenden Code definieren

public enum Verbosity 
{
   BRIEF, NORMAL, FULL, ACTION_NOT_VALID;
   private int value;

   public int getValue()
   {
     return this.value;
   } 

   public static final Verbosity getVerbosityByValue(int value)
   {
     for(Verbosity verbosity : Verbosity.values())
     {
        if(verbosity.getValue() == value)
            return verbosity ;
     }

     return ACTION_NOT_VALID;
   }

   @Override
   public String toString()
   {
      return ((Integer)this.getValue()).toString();
   }
};

finden Sie weitere Klärung folgenden Link

da Java 8 Sie die Karte in einer einzigen Zeile initialisieren können und ohne statischen Block

private static Map<String, Verbosity> stringMap = Arrays.stream(values())
                 .collect(Collectors.toMap(Enum::toString, Function.identity()));

Sie können die Enum::valueOf() Funktion verwenden, wie oben von Gareth Davis & Brad Mace vorgeschlagen, aber stellen Sie sicher, dass Sie die IllegalArgumentException behandeln, wenn die Zeichenfolge verwendet geworfen werden würde, ist in der ENUM nicht vorhanden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top