簡體   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