字符串与Java枚举的不区分大小写匹配

PNS*_*PNS 41 java generics enums

JavavalueOf()为每个Enum<T>对象提供了一个方法,所以给出了enum类似的方法

public enum Day {
  Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
Run Code Online (Sandbox Code Playgroud)

一个人可以像查找一样

Day day = Day.valueOf("Monday");
Run Code Online (Sandbox Code Playgroud)

如果传递给的字符串valueOf()与现有Day值不匹配(区分大小写),IllegalArgumentException则抛出a.

要进行不区分大小写的匹配,可以在Day枚举中编写自定义方法,例如

public static Day lookup(String day) {
  for (Day d : Day.values()) {
    if (d.name().equalsIgnoreCase(day)) {
      return type;
    }
  }
  return null;
}
Run Code Online (Sandbox Code Playgroud)

是否有任何通用的方法,在不使用值或任何其他额外对象的缓存的情况下,只编写一次lookup()上面的静态方法(即,不是每个enum),假定该values()方法Enum<E>在编译时被隐式添加到类中?

这种"通用" lookup()方法的签名与该方法类似Enum.valueOf(),即:

public static <T extends Enum<T>> T lookup(Class<T> enumType, String name);
Run Code Online (Sandbox Code Playgroud)

它将完全实现Day.lookup()任何方法的功能enum,而无需为每个方法重新编写相同的方法enum.

Ada*_*dam 38

我发现特殊混合的泛型有点棘手,但这很有效.

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;
}
Run Code Online (Sandbox Code Playgroud)

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"));
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这很有效.感谢指向`getEnumConstants()`方法的指针.我实际上试图避免通过反射调用`values()`方法,这就是`getEnumConstants()`实际上做的,但显然没有更好的方法.顺便说一句,您可以使用`equalsIgnoreCase()`进行字符串比较. (2认同)

spr*_*ter 27

我认为最简单的安全方法是:

Arrays.stream(Day.values())
    .filter(e -> e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
Run Code Online (Sandbox Code Playgroud)

或者,如果要使用类对象,则:

Arrays.stream(enumClass.getEnumConstants())
    .filter(e -> (Enum)e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
Run Code Online (Sandbox Code Playgroud)


Eni*_*igo 8

从版本3.8开始,apache commons-lang EnumUtils有两个方便的方法:

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


gbt*_*mon 8

我可以相信这一点,或者类似的解决方案尚未发布。我首选这里(绝对不需要“查找”,只是更智能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; 
    }
}
Run Code Online (Sandbox Code Playgroud)

进而:

Day day = Day.valueOfIgnoreCase("mOnDay"); 
System.out.println(day); 

>>> Monday
Run Code Online (Sandbox Code Playgroud)


Joo*_*gen 5

一个通用的解决方案是遵守常量为大写的约定。(或者在您的特定情况下,使用大写的查找字符串)。

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");
Run Code Online (Sandbox Code Playgroud)


Ale*_*jak 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;
    }
}
Run Code Online (Sandbox Code Playgroud)