首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用java泛型迭代枚举值

使用java泛型迭代枚举值
EN

Stack Overflow用户
提问于 2010-02-05 16:32:05
回答 9查看 48.1K关注 0票数 90

不确定如何做到这一点,或者这是否可能。

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

代码语言:javascript
复制
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对象的方法:

代码语言:javascript
复制
Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);

枚举的定义如下:

代码语言:javascript
复制
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:

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

代码语言:javascript
复制
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有一个非空值,这将非常有用。不幸的是,在我的用例中,这个值通常是空的,因为还有一个public Filter() no-arg构造函数。这意味着我不能在不获取NPE的情况下执行selectedOption.getClass()。这个筛选器类管理一个可用选项列表,这些选项是被选中的。如果未选择任何内容,则selectedOption为null。

所以就像这样:

代码语言:javascript
复制
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参数的情况下做到这一点吗?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-02-05 16:44:39

这确实是一个很难的问题。您需要做的一件事是告诉java您正在使用枚举。这是通过声明您扩展了泛型的Enum类来实现的。但是,这个类没有values()函数。所以你必须选择你能得到值的类。

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

代码语言:javascript
复制
public <T extends Enum<T>> void enumValues(Class<T> enumType) {
        for (T c : enumType.getEnumConstants()) {
             System.out.println(c.name());
        }
}
票数 134
EN

Stack Overflow用户

发布于 2010-02-05 16:55:22

另一种选择是使用EnumSet:

代码语言:javascript
复制
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);
    } 

}
票数 19
EN

Stack Overflow用户

发布于 2015-09-22 22:40:38

为了完整性,JDK8为我们提供了一种相对干净和简洁的方式来实现这一点,而不需要在枚举类中使用合成values()

给定一个简单的枚举:

代码语言:javascript
复制
private enum TestEnum {
    A,
    B,
    C
}

和一个测试客户端:

代码语言:javascript
复制
@Test
public void testAllValues() {
    System.out.println(collectAllEnumValues(TestEnum.class));
}

这将打印{A, B, C}

代码语言:javascript
复制
public static <T extends Enum<T>> String collectAllEnumValues(Class<T> clazz) {
    return EnumSet.allOf(clazz).stream()
            .map(Enum::name)
            .collect(Collectors.joining(", " , "\"{", "}\""));
}

代码可以简单地调整为检索不同的元素或以不同的方式收集。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2205891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档