Case-insensitive matching of a string to a Java enum

后端 未结 9 1512
独厮守ぢ
独厮守ぢ 2020-12-24 10:59

Java provides a valueOf() method for every Enum object, so given an enum like

public enum Day {
         


        
相关标签:
9条回答
  • 2020-12-24 11:21

    For Android and relatively short Enums, I do the simple loop and compare the name ignoring the case.

    public enum TransactionStatuses {
        public static TransactionStatuses from(String name) {
            for (TransactionStatuses status : TransactionStatuses.values()) {
                if (status.name().equalsIgnoreCase(name)) {
                    return status;
                }
            }
            return null;
        }
    }
    
    0 讨论(0)
  • 2020-12-24 11:21

    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");
    
    0 讨论(0)
  • 2020-12-24 11:22

    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.

    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.

    0 讨论(0)
  • 2020-12-24 11:22

    I haven't tested this yet but why not overloading these methods as mentioned in this SO answer

    public enum Regular {
        NONE,
        HOURLY,
        DAILY,
        WEEKLY;
    
        public String getName() {
            return this.name().toLowerCase();
        }    
    }

    0 讨论(0)
  • 2020-12-24 11:25

    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"));
    }
    
    0 讨论(0)
  • 2020-12-24 11:26

    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);
    
    0 讨论(0)
提交回复
热议问题