Reputation: 361
I know I can check whether a String is contained in a specific Enum using the concept described by pseudo code below(I know there's no contains
method for Enum
, that's just for my example) :
Enum Animal {
Dog,
Cat,
Human
}
public boolean CheckAnimalValid(String name){
return Animal.contains(name)? true : false;
}
But in previous way I need to implement the CheckValid method for each Enum class, since I need to know WHICH Enum class should I to check.
I want to know is there any method to pass Enum type as a parameter to a function, so that I can do in this way:
Enum Animal {
Dog,
Cat,
Person
}
Enum Plant {
Grass,
Flower,
Tree
}
public boolean CheckEnumValid(String name, what_should_I_do? enum){
return enum.contains(name)? true : false;
}
I want to know which type(or keyword) should I use in what_should_I_do? in the previous code. I know I should use Generics, but I don't know how to do. Thanks!
Upvotes: 2
Views: 17369
Reputation: 65889
Not certain if I fully understand your need but I suspect you want to lookuup in any enum
by String
- if that is the case then there are several ways to do this.
First - let's define what you are looking for - something like this?
interface Lookup<S,T> {
T lookup(S s);
}
Now you could adjust every enum
to do something like this:
enum Animal implements Lookup<String,Animal>{
Dog,
Cat,
Person;
Map<String,Animal> lookup = Arrays.stream(Animal.values())
.collect(Collectors.toMap(e -> e.name(), e -> e));
public Animal lookup(String name) {
return lookup.get(name);
}
}
But I suspect you want to do this without hacking all of your enums
- which would be a pain. Here's one method using a helper object.
class EnumLookup<E extends Enum<E>> implements Lookup<String,E> {
final Map<String,E> lookup;
public EnumLookup(Class<E> clazz) {
lookup = Arrays.stream(clazz.getEnumConstants())
.collect(Collectors.toMap(e -> e.name(), e -> e));
}
@Override
public E lookup(String s) {
return lookup.get(s);
}
}
Now you can create one of these to interrogate the enum
whenever you like.
enum Plant {
Grass,
Flower,
Tree;
}
public void test() {
EnumLookup<Plant> lookup = new EnumLookup<>(Plant.class);
System.out.println("Tree -> "+lookup.lookup("Tree"));
}
Upvotes: 1
Reputation: 30019
You can use the static method Enum.valueOf(Class<T> enumType, String name)
which returns an enum of type T
, if the name matches an enum constants of that type. Otherwise is throws an IllegalArgumentException
.
Example usage:
Enum.valueOf(Plant.class, "Flower");
Wrapped in a method that returns a boolean:
public <T extends Enum<T>> boolean checkValid(Class<T> enumType, String name){
try {
Enum.valueOf(enumType, name);
return true;
} catch(IllegalArgumentException e) {
return false;
}
}
Upvotes: 6
Reputation: 48307
It would be nice if you implement a generic method instead, java allows using contrains so you can for sure PASS ONLY AN ENUM, and thanks to interfaces you can restrict at compiling time what enums are allowed or not:
Define this generic method
public <T extends Enum<?> & ITag> void printEnum(T d) {
System.out.println(d.name());
}
define a tag interface:
interface ITag {
}
now you can Tag the enums that only valid in the method:
enum Color implements ITag {
RED, GREEN, BLUE
}
enum STATE {
ON, OFF
}
enum CONNECTION {
UDP, TCP
}
as result, you can check if a method is taking the correct param at compiling time...
printEnum(Color.GREEN); //valid
printEnum(STATE.OFF);// invalid The method printEnum(T)... is not applicable for the arguments..
printEnum(CONNECTION.UDP);// invalid The method printEnum(T)... is not applicable for the arguments..
printEnum("Green"); // invalid The method printEnum(T)... is not applicable for the arguments..
Upvotes: 0