使用Java泛型迭代枚举值

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (25)

我试图找到一种方法来遍历enum的值,同时使用泛型。不知道如何做到这一点,或者如果可能的话。

以下代码说明了我想要做的事情。请注意代码T.values()在下面的代码中无效。

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()) {  // INVALID CODE
            availableOptions.add(option);
        }
    }
}

以下是我将如何实例化一个Filter对象:

Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);

枚举定义如下:

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;
    }
}

我意识到将枚举的值复制到列表可能没有意义,但我使用的库需要一个值列表作为输入,并且不能用于枚举。

编辑2/5/2010:

大多数提出的答案都非常相似,并建议做这样的事情:

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);
        }
    }
}

如果我可以确定selectedOption具有非空值,这将工作得很好。不幸的是,在我的用例中,这个值通常为空,因为还有一个公共的Filter() no-arg构造函数。这意味着我无法在没有获得NPE的情况下执行selectedOption.getClass()。此过滤器类管理可用选项的列表,选择哪个选项。如果没有选择任何内容,selectedOption为null。

我能想到解决这个问题的唯一方法是在构造函数中实际传入一个类。所以像这样:

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);
        }
    }
}

任何想法如何做到这一点,而不需要在构造函数中额外的类参数?

提问于
用户回答回答于

这确实是一个难题。你需要做的一件事就是告诉java你正在使用一个枚举。这是说你扩展了泛型类的泛型。但是这个类没有values()函数。所以你必须参加能够获得价值的课程。

以下示例应该可以帮助您解决问题:

public <T extends Enum<T>> void enumValues(Class<T> enumType) {
        for (T c : enumType.getEnumConstants()) {
             System.out.println(c.name());
        }
}
用户回答回答于

另一种选择是使用EnumSet:

class PrintEnumConsants {

    static <E extends Enum <E>> void foo(Class<E> elemType) {
        for (E e : java.util.EnumSet.allOf(elemType)) {
            System.out.println(e);
        }
    }

    enum Color{RED,YELLOW,BLUE};
    public static void main(String[] args) {
        foo(Color.class);
    } 

}

扫码关注云+社区