使用java泛型迭代枚举值 [英] Iterate enum values using java generics

查看:286
本文介绍了使用java泛型迭代枚举值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to find a way to iterate through an enum's values while using generics. Not sure how to do this or if it is possible.

以下代码说明了我要做什么。请注意,代码 T.values()在以下代码中无效。

The following code illustrates what I want to do. Note that the code T.values() 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()) {  // INVALID CODE
            availableOptions.add(option);
        }
    }
}

这是我如何实例化一个Filter对象:

Here is how I would instantiate a Filter object:

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

我意识到复制枚举的值为列表,但是我正在使用一个需要一个值列表作为输入的库,而不能使用枚举。

I realize it might not make sense to copy a enum's values to a list, but I'm using a library that needs a list of values as input and won't work with enums.

编辑2/5/2010:

EDIT 2/5/2010:

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

Most of the answers proposed 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);
        }
    }
}

可以确保selectedOption具有非空值。不幸的是,在我的用例中,该值通常为null,因为还有一个 public Filter() no-arg构造函数。这意味着我不能做一个selectedOption.getClass(),而不会得到一个NPE。此过滤器类管理可用选项的列表,选择哪些选项。当没有选择任何内容时,selectedOption为空。

This would work great if I can be sure that selectedOption has a non-null value. Unfortunately, in my use case, this value is often null, as there is a public Filter() no-arg constructor as well. This means I can't do a selectedOption.getClass() without getting an NPE. This filter class manages a list of available options which of the options is selected. When nothing is selected, selectedOption is null.

我可以想到的唯一可以解决的问题就是实际传递给构造函数中的Class。所以这样的东西:

The only thing I can think to solve this is to actually pass in a 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);
        }
    }
}

任何想法如何做在构造函数中不需要额外的Class参数?

Any ideas how to do this without needing an extra Class parameter in the constructors?

推荐答案

这是一个很难的问题。你需要做的一件事就是告诉java你正在使用一个枚举。这是通过说明你为泛型扩展Enum类。但是这个类没有values()函数。因此,您必须参加可以获得价值的课程。

This is a hard problem indeed. One of the things you need to do is tell java that you are using an enum. This is by stating that you extend the Enum class for your generics. However this class doesn't have the values() function. So you have to take the class for which you can get the values.

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

The following example should help you fix your problem:

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

这篇关于使用java泛型迭代枚举值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆