繁体   English   中英

在Java中如何编写代码循环遍历枚举?

[英]In Java how do write code to loop round an arbitary enum?

如何编写代码循环任意枚举?

因此,在下面的代码中使用枚举作为提供创建Html select循环的值,但是我看不到如何将枚举传递给方法,或者如何访问标准的.values().ordinal()方法。 所以目前我已经对特定的枚举RenameFileOptions进行了硬编码,但是我想使用任何枚举,我可以解析枚举类,例如RenameFileOptions.class但仍然如何访问.name() .values().ordinal()

public ContainerTag addCombo(UserOption userOption, int selectedValue)
{
    return div(
                label(userOption.getLabel().getMsg())
                    .withTitle(userOption.getTooltip().getMsg()),
                select(
                    each(Arrays.asList(RenameFileOptions.values()),
                            next ->
                                iffElse(next.ordinal()==selectedValue,
                                        option(next.name()).attr(Html.SELECTED, Html.SELECTED).withValue(String.valueOf(next.ordinal())),
                                        option(next.name()).withValue(String.valueOf(next.ordinal()))
                                )
                    ))
                .withName(userOption.getOption())
            );
}

更新由于似乎没有办法以一种轻松的方式实现这一目标,所以我向每个枚举添加了一个getOptions()方法,这就是发送给我的addCombo方法的内容。 这意味着我必须重复执行我不喜欢做的代码,但这意味着addCombo()方法可以按要求工作,并且通过不引入困难的语法来使代码更易于理解。

public enum RenameFileOptions implements OptionList
{
    NO(TextLabel.RENAME_FILE_OPTION_NO),
    YES_IF_MATCHED_TO_RELEASE(TextLabel.RENAME_FILE_OPTION_YES_IF_RELEASE_MATCH),
    YES_IF_MATCHED_TO_RELEASE_OR_SONG(TextLabel.RENAME_FILE_OPTION_YES_IF_RELEASE_OR_SONG_MATCH),
    YES_IF_HAS_BASIC_METADATA(TextLabel.RENAME_FILE_OPTION_YES_IF_HAS_METADATA),
    YES_FOR_ALL_SONGS(TextLabel.RENAME_FILE_OPTION_YES),

    ;
    private TextLabel label;

    RenameFileOptions(TextLabel label)
    {
        this.label=label;
    }

    public String getName()
    {
        return label.getMsg();
    }

    public String toString()
    {
        return getName();
    }

    public static List<NameKey> getOptions()
    {
        List<NameKey> options = new ArrayList<NameKey>();
        for(RenameFileOptions next:RenameFileOptions.values())
        {
            options.add(new NameKey(next.ordinal(), next.getName()));
        }
        return options;
    }
}

public class NameKey
{
    private Integer id;
    private String name;

    public NameKey(Integer id, String name)
    {
        this.id =id;
        this.name=name;
    }
    public Integer getId()
    {
        return id;
    }

    public void setId(Integer id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}

您应该使用Class.getEnumConstants()方法。

因此,您的代码的中间部分应类似于

                each(Arrays.asList(enumClass.getEnumConstants()),
                        next ->
                            iffElse(next.ordinal()==selectedValue,
                                    option(next.name()).attr(Html.SELECTED, Html.SELECTED).withValue(String.valueOf(next.ordinal())),
                                    option(next.name()).withValue(String.valueOf(next.ordinal()))
                            )
                ))

并且您应该通过Class<? extends Enum<?>> enumClass 在方法参数中Class<? extends Enum<?>> enumClass

您可以使用EnumSet.allOf()

for(MyType t : EnumSet.allOf(MyType.class)) {
    doSomethingWith(t);
}

...或使用Java 8 lambda:

EnumSet.allOf(MyType.class).forEach( 
    t -> doSomethingWith(t)
);

尽管是Set ,但EnumSet的文档指出其迭代器产生的值“以其自然顺序 (声明枚举常量的顺序)”


对于任意枚举类:

<T extends Enum<T>> void loopAroundEnum(Class<T> enumType) {
    EnumSet.allOf(enumType).forEach(
       val -> doSomethingWith(val) // val is of type T
    );
}

尽管Java习惯是不进行过早优化,但值得一提的是,与使用MyType.getEnumConstants()返回的MyType[]数组相比, EnumSet 可能在速度和内存消耗上都更有效率。

EnumSet的Javadoc:

枚举集在内部表示为位向量。 这种表示非常紧凑和高效。 该类的时空性能应足够好,可以用作传统的基于int的“位标志”的高质量,类型安全的替代方法。

由于Enum是基类,因此您需要将Class传递给枚举:

public <E extends Enum<E>> void method(Class<E> type) {
    E[] values = type.getEnumConstants();
}

当然,Class会测试它是否为枚举。 如果没有枚举类,则返回null。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM