我有枚举类型ReportTypeEnum,在我所有的类的方法之间传递,但我需要在URL上传递这个,所以我使用序数方法来获得int值。在我的另一个JSP页面中获得它之后,我需要将它转换回ReportTypeEnum,以便我可以继续传递它。

如何将序数转换为ReportTypeEnum?

使用Java 6 SE。


当前回答

public enum Status {
    STATUS_1, STATUS_2, STATUS_3, STATUS_4;

    public static Status getStatusByOrdinal(int ordinal) {
        for (Status status : values()) {
            if (status.ordinal() == ordinal) {
                return status;
            }
        }
        return STATUS_1;
    }
}

其他回答

public enum Suit implements java.io.Serializable, Comparable<Suit>{
  spades, hearts, diamonds, clubs;
  private static final Suit [] lookup  = Suit.values();
  public Suit fromOrdinal(int ordinal) {
    if(ordinal< 1 || ordinal> 3) return null;
    return lookup[value-1];
  }
}

测试类

public class MainTest {
    public static void main(String[] args) {
        Suit d3 = Suit.diamonds;
        Suit d3Test = Suit.fromOrdinal(2);
        if(d3.equals(d3Test)){
            System.out.println("Susses");
        }else System.out.println("Fails");
    }
}

我很感激你与我们分享,如果你有一个更有效的代码,我的enum是巨大的,不断调用数千次。

要将一个序数转换为它的枚举表示,你可能想这样做:

ReportTypeEnum value = ReportTypeEnum.values()[ordinal];

请注意数组的边界。

注意,每次调用values()都会返回一个新克隆的数组,这可能会对性能产生负面影响。如果经常调用数组,可能需要缓存数组。

关于如何缓存值的代码示例()。


这个回答经过编辑,包含了评论中的反馈

这是我在Android上使用Proguard所做的:

public enum SomeStatus {
    UNINITIALIZED, STATUS_1, RESERVED_1, STATUS_2, RESERVED_2, STATUS_3;//do not change order

    private static SomeStatus[] values = null;
    public static SomeStatus fromInteger(int i) {
        if(SomeStatus.values == null) {
            SomeStatus.values = SomeStatus.values();
        }
        if (i < 0) return SomeStatus.values[0];
        if (i >= SomeStatus.values.length) return SomeStatus.values[0];
        return SomeStatus.values[i];
    }
}

它很短,我不需要担心在Proguard有一个异常

有一种简单和坏的方法,也有一种相当简单和正确的方法。

首先,简单的和坏的(这些通常很受欢迎)。枚举类方法通过values()方法返回所有可用实例的数组,您可以通过数组索引访问枚举对象。

RenderingMode mode = RenderingMode.values()[index];

//Enum Class somewhere else
public enum RenderingMode
{
    PLAYING,
    PREVIEW,
    VIEW_SOLUTION;    
    
}
    

//RenderingMode.values()[0] will return RenderingMode.PLAYING
//RenderingMode.values()[1] will return RenderingMode.PREVIEW
//Why this is bad? Because it is linked to order of declaration.

//If you later changed the order here, it will impact all your existing logic around this.
public enum RenderingMode
    {
        
        PREVIEW,
        VIEW_SOLUTION,
        PLAYING;    
        
    }
 //Now
//RenderingMode.values()[0] will return RenderingMode.PREVIEW
//RenderingMode.values()[1] will return RenderingMode.VIEW_SOLUTION

这是正确的做法。 在枚举类中创建一个静态方法fromInt。

public enum RenderingMode
{
    PLAYING,
    PREVIEW,
    VIEW_SOLUTION;

    public static RenderingModefromInt(int index)
    {
       //this is independent of order of declaration
        switch (index)
        {
            case 0: return PLAYING;
            case 1: return PREVIEW;
            case 2: return VIEW_SOLUTION;
        }
        //Consider throwing Exception here

        return null;
    }
}

每个枚举都有name(),它给出一个包含枚举成员名称的字符串。

给定一个花色{红心,黑桃,梅花,方块},Suit.Heart.name()将给出红心。

每个枚举都有一个valueOf()方法,该方法接受一个枚举类型和一个字符串,以执行相反的操作:

枚举. valueof (Suit.class, "Heart")返回Suit.Heart。

我真搞不懂为什么会有人用序数。它可能会快几纳秒,但如果枚举成员发生变化,则不安全,因为另一个开发人员可能不知道某些代码依赖于序数值(特别是在问题中引用的JSP页面中,网络和数据库开销完全占据了时间,而不是使用整数而不是字符串)。