Java
为每个valueOf()
对象提供了Enum<T>
方法,因此给出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()
方法(例如,不是每个enum
),给定values()
方法在编译时隐式添加到Enum<E>
类?
这种“通用”lookup()
方法的签名类似于Enum.valueOf()
方法,即:
public static <T extends Enum<T>> T lookup(Class<T> enumType, String name);
它将为任何Day.lookup()
实现enum
方法的功能,而无需为每个enum
重写相同的方法。
答案 0 :(得分:36)
我发现特殊混合的泛型有点棘手,但这很有效。
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"));
}
答案 1 :(得分:27)
我认为最简单的安全方法是:
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);
答案 2 :(得分:6)
从版本 3.8开始 apache commons-lang EnumUtils有两种方便的方法:
getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
答案 3 :(得分:5)
对于Android和相对较短的枚举,我执行简单的循环并比较忽略大小写的名称。
public enum TransactionStatuses {
public static TransactionStatuses from(String name) {
for (TransactionStatuses status : TransactionStatuses.values()) {
if (status.name().equalsIgnoreCase(name)) {
return status;
}
}
return null;
}
}
答案 4 :(得分:4)
如果Class
表示枚举,则可以使用Class
's getEnumConstants()
method返回所有枚举类型的数组,如果不是null
,则可以使用for (T d : enumType.getEnumConstants()) {
。
返回此枚举类的元素,如果此Class对象不表示枚举类型,则返回null。
你的增强型for循环线看起来像这样:
{{1}}
答案 5 :(得分:4)
通用的解决方案是遵守常量为大写的约定。 (或者在您的特定情况下使用查找字符串)。
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");
答案 6 :(得分:1)
它将完全实现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
}
如果在Java中有一种方法可以通过隐式添加方法来扩展Enum类,就像添加了values()方法一样,但我不认为有办法做到这一点
答案 7 :(得分:0)
我正在使用这种方式将字符串与Java枚举进行不区分大小写的匹配
Server >> Settings >> Features >> "Login Cookie Validity" a
答案 8 :(得分:0)
我还没有测试过,但是为什么不重载SO answer中提到的这些方法
public enum Regular {
NONE,
HOURLY,
DAILY,
WEEKLY;
public String getName() {
return this.name().toLowerCase();
}
}