Java
は、すべての_Enum<T>
_オブジェクトに対してvalueOf()
メソッドを提供します。したがって、enum
_public enum Day {
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
_
次のようなルックアップを行うことができます
_Day day = Day.valueOf("Monday");
_
valueOf()
に渡された文字列が既存のDay
値と一致しない(大文字と小文字を区別する)場合、IllegalArgumentException
がスローされます。
大文字と小文字を区別しないマッチングを行うには、Day
列挙内にカスタムメソッドを記述できます。
_public static Day lookup(String day) {
for (Day d : Day.values()) {
if (d.name().equalsIgnoreCase(day)) {
return type;
}
}
return null;
}
_
値や他の追加オブジェクトのキャッシュを使用せずに、上記のような静的lookup()
メソッドを1回だけ(つまり、すべてのenum
に対してではなく)記述する一般的な方法はありますかvalues()
メソッドは、コンパイル時に_Enum<E>
_クラスに暗黙的に追加されますか?
このような「汎用」lookup()
メソッドのシグネチャは、Enum.valueOf()
メソッドに似ています。つまり、次のようになります。
_public static <T extends Enum<T>> T lookup(Class<T> enumType, String name);
_
そして、各enum
に同じメソッドを書き直す必要なく、enum
に対してDay.lookup()
メソッドの機能を正確に実装します。
ジェネリックの特別なブレンドを得るのは少し難しいと感じましたが、これはうまくいきます。
public static <T extends Enum<?>> T searchEnum(Class<T> enumeration,
String search) {
for (T each : enumeration.getEnumConstants()) {
if (each.name().compareToIgnoreCase(search) == 0) {
return each;
}
}
return null;
}
例
public enum Horse {
THREE_LEG_JOE, GLUE_FACTORY
};
public static void main(String[] args) {
System.out.println(searchEnum(Horse.class, "Three_Leg_Joe"));
System.out.println(searchEnum(Day.class, "ThUrSdAy"));
}
最も簡単で安全な方法は次のとおりだと思います。
Arrays.stream(Day.values())
.filter(e -> e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
または、クラスオブジェクトを使用する場合:
Arrays.stream(enumClass.getEnumConstants())
.filter(e -> (Enum)e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
バージョン3.8以降、Apache commons-lang EnumUtils には2つの便利なメソッドがあります:
getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
一般的な解決策は、定数は大文字という規則に従うことです。 (または特定のケースでは、検索文字列の大文字を使用します)。
public static <E extends Enum<E>> E lookup(Class<E> enumClass,
String value) {
String canonicalValue.toUpperCase().replace(' ', '_');
return Enum<E>.valueOf(enumClass, canonicalValue);
}
enum Day(MONDAY, ...);
Day d = lookup(Day,class, "thursday");
Androidと比較的短いEnumsの場合、単純なループを実行し、大文字小文字を無視して名前を比較します。
public enum TransactionStatuses {
public static TransactionStatuses from(String name) {
for (TransactionStatuses status : TransactionStatuses.values()) {
if (status.name().equalsIgnoreCase(name)) {
return status;
}
}
return null;
}
}
Class
のgetEnumConstants()
メソッド を使用できます。これは、Class
がenumを表す場合、すべての列挙型の配列を返すか、null
そうでない場合。
この列挙クラスの要素を返します。このClassオブジェクトが列挙型を表さない場合はnullを返します。
拡張forループ行は次のようになります。
for (T d : enumType.getEnumConstants()) {
また、列挙型ごとに同じメソッドを書き直す必要なく、列挙型に対してDay.lookup()メソッドの機能を正確に実装します。
おそらく、次のようにそれを行うためのユーティリティクラスを作成できます。
public class EnumUtil {
private EnumUtil(){
//A utility class
}
public static <T extends Enum<?>> T lookup(Class<T> enumType,
String name) {
for (T enumn : enumType.getEnumConstants()) {
if (enumn.name().equalsIgnoreCase(name)) {
return enumn;
}
}
return null;
}
// Just for testing
public static void main(String[] args) {
System.out.println(EnumUtil.lookup(Day.class, "friday"));
System.out.println(EnumUtil.lookup(Day.class, "FrIdAy"));
}
}
enum Day {
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
Values()メソッドを追加する方法だけで暗黙的にメソッドを追加することでEnumクラスを拡張する方法がJavaにあれば良かったのですが、その方法。
Java enum Day[] days = Day.values(); for(Day day: days) { System.out.println("MONDAY".equalsIgnoreCase(day.name())); }
への文字列の大文字と小文字を区別しないマッチングにこの方法を使用しています。