185

文字列値 (またはおそらく他の値) から列挙型を検索したいと思います。次のコードを試しましたが、イニシャライザで static を使用できません。簡単な方法はありますか?

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

12 に答える 12

265

valueOfEnumごとに自動生成されるメソッドを使用します。

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

任意の値の場合:

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

プロファイラーに指示された場合にのみ、Map の実装に進みます。

すべての値を繰り返し処理していることは知っていますが、列挙型の値が 3 つしかない場合、他の努力をする価値はほとんどありません。

于 2009-07-03T21:34:01.553 に答える
160

あなたは近くにいます。任意の値については、次のようなことを試してください。

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);
    }
}
于 2009-07-03T21:33:39.917 に答える
33

Java 8 では、次の方法で実現できます。

public static Verbosity findByAbbr(final String abbr){
    return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
于 2017-08-20T05:00:20.773 に答える
13

@Lyleの答えはかなり危険であり、特に列挙型を静的内部クラスにすると機能しないことがわかりました。代わりに、列挙型の前に BootstrapSingleton マップをロードするこのようなものを使用しました。

編集 これは、最新の JVM (JVM 1.6 以降) ではもう問題にならないはずですが、JRebel にはまだ問題があると思いますが、再テストする機会はありませんでした

最初にロードしてください:

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

次に、列挙型コンストラクターにロードします。

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

内部列挙型がある場合は、列挙型定義の上にマップを定義するだけで、(理論的には) 前にロードする必要があります。

于 2012-07-18T16:10:28.700 に答える
7

そして、 valueOf()を使用できませんか?

編集:ところで、列挙型で static { } を使用することを妨げるものは何もありません。

于 2009-07-03T21:31:50.637 に答える
0

おそらく、これを見てください。それは私のために働いています。これの目的は、「RED」を「/red_color」で検索することです。aを宣言し、それにsを1回だけstatic mapロードすると、 sが多いenum場合に、パフォーマンス上の利点が得られます。enum

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

あなたの意見を入れてください。

于 2013-03-14T06:24:34.570 に答える
-2

上記の Gareth Davis と Brad Mace によって提案された関数を使用できますが、使用された文字列が列挙型に存在しない場合にスローされるEnum::valueOf()を必ず処理してください。IllegalArgumentException

于 2013-06-15T17:25:19.070 に答える