字符串与 Java 枚举的不区分大小写的匹配
Case-insensitive matching of a string to a Java enum
Java
为每个 Enum<T>
对象提供了一个 valueOf()
方法,所以给定一个 enum
like
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()
方法(即,不是每个 enum
),鉴于 values()
方法在编译时隐式添加到 Enum<E>
class?
这种 "generic" lookup()
方法的签名类似于 Enum.valueOf()
方法,即:
public static <T extends Enum<T>> T lookup(Class<T> enumType, String name);
并且它将为任何 enum
实现 Day.lookup()
方法的功能,而无需为每个 enum
.[=32= 重写相同的方法]
您可以使用 Class
's getEnumConstants()
method,其中 returns 所有枚举类型的数组,如果 Class
表示枚举,否则 null
。
Returns the elements of this enum class or null if this Class object does not represent an enum type.
您的增强 for 循环行如下所示:
for (T d : enumType.getEnumConstants()) {
我认为最简单安全的方法是:
Arrays.stream(Day.values())
.filter(e -> e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
或者如果您想使用 class 对象,则:
Arrays.stream(enumClass.getEnumConstants())
.filter(e -> (Enum)e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
我发现获得泛型的特殊混合有点棘手,但这很有效。
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"));
}
一个通用的解决方案是遵守常量大写 的约定。 (或者在您的特定情况下使用查找字符串的大写字母)。
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");
and it would implement exactly the functionality of the Day.lookup()
method for any enum, without the need to re-write the same method for
each enum.
也许您可以编写一个实用程序 class 来执行此操作,如下所示。
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
}
如果 Java 中有一种方法可以让我们通过隐式添加方法来扩展 Enum class 就像添加 values() 方法一样,那就太好了,但我没有认为有办法做到这一点。
对于 Android 和相对较短的枚举,我执行简单的循环并比较忽略大小写的名称。
public enum TransactionStatuses {
public static TransactionStatuses from(String name) {
for (TransactionStatuses status : TransactionStatuses.values()) {
if (status.name().equalsIgnoreCase(name)) {
return status;
}
}
return null;
}
}
从版本 3.8 开始,apache commons-lang EnumUtils 有两个方便的方法:
getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
我正在使用这种方式将字符串与 java 枚举进行不区分大小写的匹配
Day[] days = Day.values();
for(Day day: days) {
System.out.println("MONDAY".equalsIgnoreCase(day.name()));
}
我还没有对此进行测试,但为什么不重载本文中提到的这些方法
public enum Regular {
NONE,
HOURLY,
DAILY,
WEEKLY;
public String getName() {
return this.name().toLowerCase();
}
}
我相信这个,或者类似的解决方案还没有发布。我更喜欢去这里(绝对不需要 'lookup',只需要一个更聪明的 valueOf
。另外,作为奖励,枚举值都是大写的,因为我们以前的 c++ 人认为他们应该是...
public enum Day {
MONDAY("Monday"),
TUESDAY("Tuesday"),
WEDNESDAY("Wednesday"),
THURSDAY("Thursday"),
FRIDAY("Friday"),
SATURDAY("Saturday"),
SUNDAY("Sunday");
public static Day valueOfIgnoreCase(String name) {
return valueOf(name.toUpperCase());
}
private final String displayName;
Day(String displayName) {
this.displayName = displayName;
}
@Override
public String toString() {
return this.displayName;
}
}
然后:
Day day = Day.valueOfIgnoreCase("mOnDay");
System.out.println(day);
>>> Monday
Java
为每个 Enum<T>
对象提供了一个 valueOf()
方法,所以给定一个 enum
like
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()
方法(即,不是每个 enum
),鉴于 values()
方法在编译时隐式添加到 Enum<E>
class?
这种 "generic" lookup()
方法的签名类似于 Enum.valueOf()
方法,即:
public static <T extends Enum<T>> T lookup(Class<T> enumType, String name);
并且它将为任何 enum
实现 Day.lookup()
方法的功能,而无需为每个 enum
.[=32= 重写相同的方法]
您可以使用 Class
's getEnumConstants()
method,其中 returns 所有枚举类型的数组,如果 Class
表示枚举,否则 null
。
Returns the elements of this enum class or null if this Class object does not represent an enum type.
您的增强 for 循环行如下所示:
for (T d : enumType.getEnumConstants()) {
我认为最简单安全的方法是:
Arrays.stream(Day.values())
.filter(e -> e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
或者如果您想使用 class 对象,则:
Arrays.stream(enumClass.getEnumConstants())
.filter(e -> (Enum)e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
我发现获得泛型的特殊混合有点棘手,但这很有效。
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"));
}
一个通用的解决方案是遵守常量大写 的约定。 (或者在您的特定情况下使用查找字符串的大写字母)。
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");
and it would implement exactly the functionality of the Day.lookup() method for any enum, without the need to re-write the same method for each enum.
也许您可以编写一个实用程序 class 来执行此操作,如下所示。
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
}
如果 Java 中有一种方法可以让我们通过隐式添加方法来扩展 Enum class 就像添加 values() 方法一样,那就太好了,但我没有认为有办法做到这一点。
对于 Android 和相对较短的枚举,我执行简单的循环并比较忽略大小写的名称。
public enum TransactionStatuses {
public static TransactionStatuses from(String name) {
for (TransactionStatuses status : TransactionStatuses.values()) {
if (status.name().equalsIgnoreCase(name)) {
return status;
}
}
return null;
}
}
从版本 3.8 开始,apache commons-lang EnumUtils 有两个方便的方法:
getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
我正在使用这种方式将字符串与 java 枚举进行不区分大小写的匹配
Day[] days = Day.values();
for(Day day: days) {
System.out.println("MONDAY".equalsIgnoreCase(day.name()));
}
我还没有对此进行测试,但为什么不重载本文中提到的这些方法
public enum Regular {
NONE,
HOURLY,
DAILY,
WEEKLY;
public String getName() {
return this.name().toLowerCase();
}
}
我相信这个,或者类似的解决方案还没有发布。我更喜欢去这里(绝对不需要 'lookup',只需要一个更聪明的 valueOf
。另外,作为奖励,枚举值都是大写的,因为我们以前的 c++ 人认为他们应该是...
public enum Day {
MONDAY("Monday"),
TUESDAY("Tuesday"),
WEDNESDAY("Wednesday"),
THURSDAY("Thursday"),
FRIDAY("Friday"),
SATURDAY("Saturday"),
SUNDAY("Sunday");
public static Day valueOfIgnoreCase(String name) {
return valueOf(name.toUpperCase());
}
private final String displayName;
Day(String displayName) {
this.displayName = displayName;
}
@Override
public String toString() {
return this.displayName;
}
}
然后:
Day day = Day.valueOfIgnoreCase("mOnDay");
System.out.println(day);
>>> Monday