I am trying to find a way to iterate over enum values using generics. Not sure how to do this or if it is possible.
The following code illustrates what I want to do. Note that the T.values () code is not valid in the following code.
public class Filter<T> { private List<T> availableOptions = new ArrayList<T>(); private T selectedOption; public Filter(T selectedOption) { this.selectedOption = selectedOption; for (T option : T.values()) {
Here's how I would instantiate a Filter object:
Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);
The listing is defined as follows:
public enum TimePeriod { ALL("All"), FUTURE("Future"), NEXT7DAYS("Next 7 Days"), NEXT14DAYS("Next 14 Days"), NEXT30DAYS("Next 30 Days"), PAST("Past"), LAST7DAYS("Last 7 Days"), LAST14DAYS("Last 14 Days"), LAST30DAYS("Last 30 Days"); private final String name; private TimePeriod(String name) { this.name = name; } @Override public String toString() { return name; } }
I understand that it makes no sense to copy enumeration values to a list, but I use a library that needs a list of values as input and will not work with enumerations.
EDIT 2/5/2010:
Most of the suggested answers are very similar and suggest doing something like this:
class Filter<T extends Enum<T>> { private List<T> availableOptions = new ArrayList<T>(); private T selectedOption; public Filter(T selectedOption) { Class<T> clazz = (Class<T>) selectedOption.getClass(); for (T option : clazz.getEnumConstants()) { availableOptions.add(option); } } }
This will work fine if I can be sure that selectedOption has a non-zero value. Unfortunately, in my use case, this value is often null because there is a public Filter () no-arg constructor. This means that I cannot do selectedOption.getClass () without getting an NPE. This filter class manages the list of available options, which is selected from these options. When nothing is selected, Option is set to null.
The only thing I can decide is to actually pass the class in the constructor. So something like this:
class Filter<T extends Enum<T>> { private List<T> availableOptions = new ArrayList<T>(); private T selectedOption; public Filter(Class<T> clazz) { this(clazz,null); } public Filter(Class<T> clazz, T selectedOption) { this.selectedOption = selectedOption; for (T option : clazz.getEnumConstants()) { availableOptions.add(option); } } }
Any ideas how to do this without requiring an additional class parameter in the constructors?