web-dev-qa-db-ja.com

文字列の大文字と小文字を区別しないJava enum

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()メソッドの機能を正確に実装します。

39
PNS

ジェネリックの特別なブレンドを得るのは少し難しいと感じましたが、これはうまくいきます。

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"));
}
36
Adam

最も簡単で安全な方法は次のとおりだと思います。

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);
27
sprinter

バージョン3.8以降、Apache commons-lang EnumUtils には2つの便利なメソッドがあります:

  • getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
  • isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
7
Enigo

一般的な解決策は、定数は大文字という規則に従うことです。 (または特定のケースでは、検索文字列の大文字を使用します)。

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");
5
Joop Eggen

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;
    }
}
5
Alen Siljak

ClassgetEnumConstants()メソッド を使用できます。これは、Classがenumを表す場合、すべての列挙型の配列を返すか、nullそうでない場合。

この列挙クラスの要素を返します。このClassオブジェクトが列挙型を表さない場合はnullを返します。

拡張forループ行は次のようになります。

for (T d : enumType.getEnumConstants()) {
4
rgettman

また、列挙型ごとに同じメソッドを書き直す必要なく、列挙型に対して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にあれば良かったのですが、その方法。

1
Nandana

Java enum Day[] days = Day.values(); for(Day day: days) { System.out.println("MONDAY".equalsIgnoreCase(day.name())); }への文字列の大文字と小文字を区別しないマッチングにこの方法を使用しています。

0
Atul Jain