文字列値(またはその他の値)から列挙型を検索したいと思います。次のコードを試しましたが、初期化子で静的を許可していません。簡単な方法はありますか?
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);
}
};
列挙ごとに自動的に作成されるvalueOf
メソッドを使用します。
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つの列挙値だけで他の努力の価値はほとんどありません。実際、あなたが多くの値を持っていない限り、マップで気にしないでしょう、それは十分に高速です。
あなたは近いです。任意の値については、次のようなものを試してください。
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);
}
}
Java 8では、次の方法で実現できます。
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
@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>();
}
次に、enumコンストラクターでロードします。
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);
}
}
内部列挙型がある場合、列挙型定義の上にMapを定義するだけで、(理論的には)前にロードされるはずです。
valueOf() ?は使用できません
編集:ところで、列挙型で静的{}を使用することを妨げるものは何もありません。
Java Language Specification 7には 例 !があります。これは、自己参照を使用したマップの初期化に関する質問を反映しています。
他の人に役立つ場合は、ここにリストされていない、私が好むオプションは GuavaのMaps機能 を使用します:
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);
}
}
デフォルトでは、null
を使用できます。throw IllegalArgumentException
またはfromString
は、Optional
を返すことができます。
おそらく、これを見てください。私のために働いています。これの目的は、「/ red_color」で「RED」を検索することです。 static map
を宣言し、enum
sを一度だけロードすると、enum
sが多い場合にパフォーマンス上の利点が得られます。
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);
}
}
}
}
ご意見をお聞かせください。
次のコードとして列挙を定義できます:
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();
}
};
Java 8以降では、静的ブロックなしで1行でマップを初期化できます。
private static Map<String, Verbosity> stringMap = Arrays.stream(values())
.collect(Collectors.toMap(Enum::toString, Function.identity()));