方便地在枚举和整数/字符串之间映射

2022-08-31 09:14:58

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

public enum BonusType {
  MONTHLY, YEARLY, ONE_OFF
}

只要我留在我的代码中,就可以正常工作。但是,我经常需要与出于相同目的使用纯(或)值的其他代码进行交互,或者我需要从/写入数据存储为数字或字符串的数据库。intString

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

从枚举到 int 很容易:

public enum BonusType {
  public final int id;

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

然后,我可以以 .BonusType x = MONTHLY; int id = x.id;

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

BonusType bt = BonusType.getById(2); 

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

  • 将查找方法放入枚举中,该方法用于填充映射“int ->枚举”,然后缓存该方法并将其用于查找。可以工作,但是我必须将此方法以相同的方式复制到我使用的每个枚举中:-(。BonusType.values()
  • 将查找方法放入静态实用工具类中。然后,我只需要一个“查找”方法,但我必须调整反射才能使其适用于任意枚举。

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

还有其他想法/见解吗?


答案 1

枚举 → int

yourEnum.ordinal()

整型→枚举

EnumType.values()[someInt]

字符串→枚举

EnumType.valueOf(yourString)

枚举→字符串

yourEnum.name()

附注:
正如您正确指出的那样,每个版本可能“不稳定”。这就是我总是将常量作为字符串存储在数据库中的确切原因。(实际上,在使用MySql时,我将它们存储为MySql枚举ordinal()


答案 2

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接口的事实。