Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,如何编写循环任意枚举的代码?_Java_Enums - Fatal编程技术网

在Java中,如何编写循环任意枚举的代码?

在Java中,如何编写循环任意枚举的代码?,java,enums,Java,Enums,如何编写循环任意枚举的代码 因此,在下面的代码中,使用枚举作为创建Html选择循环所提供的值,但我看不到如何将枚举传递给该方法,或者如何访问标准的.values()和.ordinal()方法。因此,目前我已经硬编码了一个特定的枚举重命名操作,但我想使用任何枚举,我可以解析枚举类,例如重命名操作.class,但我仍然要如何访问.name(),.values()和.ordinal() 更新 由于似乎没有办法以非黑客方式实现这一点,我转而向每个枚举添加了一个getOptions()方法,这就是发送到a

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

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

更新 由于似乎没有办法以非黑客方式实现这一点,我转而向每个枚举添加了一个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;
    }
}
公共枚举重命名选项实现OptionList
{
否(TextLabel.RENAME\u FILE\u OPTION\u NO),
是\u如果与发布匹配(文本标签。重命名文件\u选项\u是\u如果与发布匹配),
是,如果与发行版或歌曲匹配(文本标签。重命名文件选项,如果发行版或歌曲匹配,则为是),
是\u如果\u有\u基本\u元数据(TextLabel.重命名\u文件\u选项\u是\u如果\u有\u元数据),
是\u所有歌曲(文本标签。重命名\u文件\u选项\u是),
;
私人文本标签;
重命名选项(文本标签标签)
{
这个标签=标签;
}
公共字符串getName()
{
返回label.getMsg();
}
公共字符串toString()
{
返回getName();
}
公共静态列表getOptions()
{
列表选项=新建ArrayList();
for(RenameFileOptions下一步:RenameFileOptions.values())
{
添加(新名称键(next.ordinal(),next.getName());
}
返回选项;
}
}
公共类名称密钥
{
私有整数id;
私有字符串名称;
公钥(整数id、字符串名称)
{
this.id=id;
this.name=name;
}
公共整数getId()
{
返回id;
}
公共无效集合id(整数id)
{
this.id=id;
}
公共字符串getName()
{
返回名称;
}
公共void集合名(字符串名)
{
this.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>enumClass

因为Enum是基类,您需要向Enum传递一个类:

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

当然,类有一个测试是否是枚举;当没有枚举类时,它返回null。

您可以使用
EnumSet.allOf()

。。。或使用Java 8 lambdas:

EnumSet.allOf(MyType.class).forEach( 
    t -> doSomethingWith(t)
);
尽管是一个
枚举集
的文档声明其迭代器“按其自然顺序(声明枚举常量的顺序)”生成值


对于任意枚举类:

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

尽管Java习惯于不过早地进行优化,但值得一提的是,
EnumSet
在速度和内存消耗方面可能比使用
MyType[]
数组(由
MyType.getenumcontents()
返回)更有效

EnumSet
的Javadoc:

枚举集在内部表示为位向量。这 表示非常紧凑和高效。时空 该类的性能应该足够好,以允许将其用作 高质量的、类型安全的替代传统的基于int的“bit” 旗帜。”


@迈克尔有点匆忙,纠正了一下。我本来想修改原始代码,但我特别想提供一种类型安全的用法,将类参数限制为枚举。否则会出现NullPointerException困难。但是
EnumSet.allOf
也是一个很好的方法-尽管我更喜欢getEnumConstants。您有两个函数式答案,但我强烈建议您不要这样做。依赖枚举序号是一个巨大的错误。如果有人决定重新组织枚举常量的顺序(例如,将它们按字母顺序排列),您的代码将以奇怪和意外的方式中断。@Michael,但这些类的唯一目的是表示可能的选项及其顺序,因此这似乎是一种很好的方法,您会推荐什么替代方法?如果只是顺序,HTML输出中不需要包含
ordinal()
。风险在于,您正在两台负载平衡的服务器上运行此操作。在中间添加一个选项。在部署期间,用户加载一个表单,其中5=取消。单击它并将“5”提交到一个新服务器,其中5=订单。序号表示所选选项,不能使用名称,因为这取决于语言(即用户可能使用英语或德语)。谢谢,这是可行的,但不幸的是,我意识到我需要使用getName()而不是name(),(此表单的所有枚举都使用一个名称参数,该参数是显示名称)因此,我如何才能使其正常工作,我可以让我的枚举使用getName()方法实现一个接口,但如果方法参数是interface而不是enum,我将无法访问ordinal()ectera?我不认为有一个直接的解决方案,但你可以这样做:不使用我为参数提供的语法,而是为方法声明类型generic,比如
,好的,谢谢,我理解,但因为我不想成为一个滥用者,我将采取另一种方法,向枚举本身添加一个静态方法,返回一个li名称键对中的st个,每个都包含getName()和ordinal()的值,谢谢,但解决方案的问题是您仍然需要指定
EnumSet.allOf(MyType.class).forEach( 
    t -> doSomethingWith(t)
);
<T extends Enum<T>> void loopAroundEnum(Class<T> enumType) {
    EnumSet.allOf(enumType).forEach(
       val -> doSomethingWith(val) // val is of type T
    );
}