A common desire in my project is to find an enum when given one of its constructed values. For example:
public enum Animal {
DOG("bark"),
CAT("meow");
public final String sound;
Animal(String sound) {
this.sound = sound;
}
public String getSound() {
return sound;
}
}
If given the string "meow", I want to get a CAT
The easy solution is to write a search method that iterates over the values of the Enum
public static Animal getBySound(String sound) {
for(Animal e : values()){
if(e.sound.equals(sound)){
return e;
}
}
}
But this has to be done individually, for every enum defined. Is there a way, given an Enum class and a method that gets a field's value, you can get the enum who's specified field matches the input?
Possible signature:
public static <T extends Enum<T>, V> Optional<T> findEnumByValue(Class<T> enumClass, Function<T, V> fieldGetter, V valueToMatch)
The closest I've gotten is this, but having the first argument be Enum[] is just one step away from being fully type-safe (as the method could be supplied an arbitrary array of enums)
public static <T extends Enum<T>, V> Optional<T> findEnumByValue(T[] enums, Function<T, V> fieldGetter, V valueMatch) {
return Arrays.stream(enums).filter(element -> Objects.equals(fieldGetter.apply(element), valueMatch)).findFirst();
}
// Example usage
Animal animal = findEnumByValue(Animal.values(), Animal::getSound, "meow").orElse(CAT);
It seems that part of the difficulty is that the static method values() that is a part of every Enum class is not accessible through the Class object.
It seems that part of the difficulty is that the static method values() that is a part of every Enum class is not accessible through the Class object.
This is not an issue: you can use EnumSet.allOf(Class) to access all enum values for a given enum Class. You can then use that like a normal Set, including streaming over it.
Optional<Animal> anAnimalThatMeows =
EnumSet
.allOf(Animal.class)
.stream()
.filter(( Animal animal ) -> animal.getSound().equals("meow"))
.findAny() ;
See this code run at Ideone.com.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With