问题

使用只能获取有限数量值的变量/参数时,我尝试始终使用Java的enum,如

public enum BonusType {
  MONTHLY, YEARLY, ONE_OFF
}

只要我留在我的代码中,就可以了。但是,我经常需要与使用plainint(或String)值的其他代码进行交互以达到相同的目的,或者我需要从/向数据库读取/写入数据,其中数据存储为数字或字符串。

在这种情况下,我想有一种方便的方法将每个枚举值与一个整数相关联,这样我就可以转换两种方式(换句话说,我需要一个"可逆枚举")。

从枚举到int很容易:

public enum BonusType {
  public final int id;

  BonusType(int id) {
    this.id = id;
  }
  MONTHLY(1), YEARLY(2), ONE_OFF(3);
}

然后我可以访问int值asBonusType x = MONTHLY; int id = x.id;

但是,我看不出相反的好方法,即从int到enum。理想情况下,像

BonusType bt = BonusType.getById(2);

我能想出的唯一解决方案是:

  • 将查找方法放入枚举中,使用BonusType.values()填充 Map "int - > enum",然后缓存并使用它进行查找。会工作,但我必须将这个方法完全复制到我使用的每个枚举中:-(。
  • 将查找方法放入静态实用程序类中。然后我只需要一个"查找"方法,但我必须摆弄反射才能让它适用于任意枚举。

对于这样一个简单的(?)问题,这两种方法看起来都非常尴尬。

还有其他想法/见解吗?


#1 热门回答(318 赞)

enum→int

yourEnum.ordinal()

int→enum

EnumType.values()[someInt]

String→enum

EnumType.valueOf(yourString)

enum→String

yourEnum.name()

附注:
正如你正确指出的那样,ordinal()可能在版本之间"不稳定"。这就是为什么我总是将常量存储为数据库中的字符串的确切原因。 (实际上,当使用MySql时,我将它们存储为MySql enums!)


#2 热门回答(35 赞)

http://www.javaspecialists.co.za/archive/Issue113.html
解决方案的开头与你的类似,int值作为枚举定义的一部分。然后他继续创建一个基于泛型的查找工具:

public class ReverseEnumMap<V extends Enum<V> & EnumConverter> {
    private Map<Byte, V> map = new HashMap<Byte, V>();
    public ReverseEnumMap(Class<V> valueType) {
        for (V v : valueType.getEnumConstants()) {
            map.put(v.convert(), v);
        }
    }

    public V get(byte num) {
        return map.get(num);
    }
}

这个解决方案很好,不需要"摆弄反射",因为它基于所有枚举类型隐式继承Enum接口的事实。


#3 热门回答(26 赞)

我在网上发现了这个,它非常有用且易于实现。这个解决方案不是我做的
http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks

public enum Status {
 WAITING(0),
 READY(1),
 SKIPPED(-1),
 COMPLETED(5);

 private static final Map<Integer,Status> lookup 
      = new HashMap<Integer,Status>();

 static {
      for(Status s : EnumSet.allOf(Status.class))
           lookup.put(s.getCode(), s);
 }

 private int code;

 private Status(int code) {
      this.code = code;
 }

 public int getCode() { return code; }

 public static Status get(int code) { 
      return lookup.get(code); 
 }

}


原文链接