字符串与 Java 枚举的不区分大小写匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28332924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Case-insensitive matching of a string to a Java enum
提问by PNS
Java
provides a valueOf()
method for every Enum<T>
object, so given an enum
like
Java
valueOf()
为每个Enum<T>
对象提供一个方法,所以给定一个enum
喜欢
public enum Day {
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
one can do a lookup like
一个可以做一个查找
Day day = Day.valueOf("Monday");
If the string passed to valueOf()
does not match (case sensitive) an existing Day
value, an IllegalArgumentException
is thrown.
如果传递给的字符串valueOf()
与现有Day
值不匹配(区分大小写),IllegalArgumentException
则抛出an 。
To do a case-insensitive matching, one can write a custom method inside the Day
enum, e.g.
要进行不区分大小写的匹配,可以在Day
枚举中编写自定义方法,例如
public static Day lookup(String day) {
for (Day d : Day.values()) {
if (d.name().equalsIgnoreCase(day)) {
return type;
}
}
return null;
}
Is there any generic way, without using caching of values or any other extra objects, to write a static lookup()
method like the above only once (i.e., not for every enum
), given that the values()
method is implicitly added to the Enum<E>
class at compile time?
考虑到该方法在编译时隐式添加到类中,是否有任何通用方法,而不使用值或任何其他额外对象的缓存,只编写一次lookup()
像上面这样的静态方法(即,不是每个enum
)?values()
Enum<E>
The signature of such a "generic" lookup()
method would be similar to the Enum.valueOf()
method, i.e.:
这种“通用”lookup()
方法的签名将类似于该Enum.valueOf()
方法,即:
public static <T extends Enum<T>> T lookup(Class<T> enumType, String name);
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
.
并且它将Day.lookup()
为 any完全实现方法的功能enum
,而无需为每个 重新编写相同的方法enum
。
采纳答案by Adam
I found getting the special blend of generics a little tricky, but this works.
我发现获得泛型的特殊混合有点棘手,但这是有效的。
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;
}
Example
例子
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"));
}
回答by rgettman
You can use Class
's getEnumConstants()
method, which returns an array of all the enum types, if the Class
represents an enum, or null
if not.
您可以使用Class
的getEnumConstants()
方法,它返回所有枚举类型的数组,如果Class
代表一个枚举,或者null
如果不是。
Returns the elements of this enum class or null if this Class object does not represent an enum type.
如果此 Class 对象不表示枚举类型,则返回此枚举类的元素或 null。
Your enhanced for loop line would look like this:
您增强的 for 循环行将如下所示:
for (T d : enumType.getEnumConstants()) {
回答by sprinter
I would think the easiest safe way to do it would be:
我认为最简单安全的方法是:
Arrays.stream(Day.values())
.filter(e -> e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
Or if you want to use the class object, then:
或者,如果您想使用类对象,则:
Arrays.stream(enumClass.getEnumConstants())
.filter(e -> (Enum)e.name().equalsIgnoreCase(dayName)).findAny().orElse(null);
回答by Joop Eggen
A generic solution would be to keeo to the convention that constants are uppercase. (Or in your specific case use a capitalize on the look-up string).
一个通用的解决方案是遵守常量大写的约定。(或者在您的特定情况下使用查找字符串的大写)。
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");
回答by Nandana
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.
并且它将为任何枚举完全实现 Day.lookup() 方法的功能,而无需为每个枚举重新编写相同的方法。
Probably you can write a utility class for doing that as the following.
可能您可以编写一个实用程序类来执行此操作,如下所示。
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
}
It would have been nice if there was a way in Java for us to extend the Enum class by implicitly adding methods just the way values() method is added but I don't think there is a way to do that.
如果 Java 中有一种方法可以让我们通过隐式添加方法来扩展 Enum 类,就像添加 values() 方法一样,但我认为没有办法做到这一点。
回答by Alen Siljak
For Android and relatively short Enums, I do the simple loop and compare the name ignoring the case.
对于 Android 和相对较短的 Enum,我执行简单的循环并比较忽略大小写的名称。
public enum TransactionStatuses {
public static TransactionStatuses from(String name) {
for (TransactionStatuses status : TransactionStatuses.values()) {
if (status.name().equalsIgnoreCase(name)) {
return status;
}
}
return null;
}
}
回答by Enigo
Starting from version 3.8apache commons-lang EnumUtilshas two handy methods for this:
从版本3.8开始,apache commons-lang EnumUtils有两个方便的方法:
getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
回答by Atul Jain
I am using this way for case-insensitive matching of a string to a java enum
Day[] days = Day.values();
for(Day day: days) {
System.out.println("MONDAY".equalsIgnoreCase(day.name()));
}
我使用这种方式将字符串与 java 枚举进行不区分大小写的匹配
Day[] days = Day.values();
for(Day day: days) {
System.out.println("MONDAY".equalsIgnoreCase(day.name()));
}