【问题标题】:Java cast Long to Enum type issueJava 将 Long 转换为 Enum 类型问题
【发布时间】:2011-08-29 12:45:57
【问题描述】:

我在将 Java long 类型转换为 Enum 类型时遇到了一点问题,找不到解决方案。

这是我正在使用的:

public enum DataType {
    IMAGES(1),
    VIDEOS(2);

    private int value;
    private DataType(int i){
        this.value = i;
    }
}

我需要这样做:

DataType dataType;
String thiz = "1";
long numb = Long.parseLong(thiz);
dataType = numb;

我得到的错误是:

将 numb 转换为 DataType 或将 dataType 转换为 long。

第二种情况:

我有这个:

static String[] packetType;
String tmp=incomingData.toString(); // where incomingData is byte[]
int lastLoc = 0;
int needsSize = packetFieldSizes[tmpCurrentField-1]; // where packetFieldSizes,tmpCurrentField are integers.
thiz=tmp.substring(lastLoc, needsSize);    

packetType=thiz;  // packetType = thiz copy; where thiz is the same as used above.

我尝试将 thiz 转换为 String[] 并使用 valueOf,但是

有什么建议可以让这些想法发挥作用吗?

提前致谢!

【问题讨论】:

  • 你不能有超过 30K 的枚举值,这使得 long 甚至 int 对于你需要的东西来说太过分了。
  • 所以你推荐我使用 int 而不是 long?
  • 不清楚您所说的“我试图将其转换为 String[] 并使用 valueOf”。
  • 还要注意String tmp=incomingData.toString(); // where incomingData is byte[]由于编码不匹配容易出错。使用new String(byte[],charsetName)
  • 对不起,我必须尝试将 thiz 转换为 String[]。

标签: java casting enums long-integer primitive-types


【解决方案1】:

Enum 已经为它的每个实例提供了一个唯一的整数。查看ordinal()。 (请注意,它是从零开始的。)

如果您需要从 long 转到 DataType,您可以这样做

DataType dataType;
String thiz;
long numb = Long.parseLong(thiz);
dataType = DataType.values()[(int) numb];

可以在此答案中找到从和到枚举常量、字符串和整数的完整转换列表:

【讨论】:

  • 为每个枚举常量拥有自己的id 在您拥有此 ID 的情况下是一种很好的做法,因为当您在其间插入新常量时,ordinal() 可能会更改为同一项目。
  • 要消除警告,您应该使用演员表:DataType.values ()[(int) numb]; 我猜 VIDEOS 作为 1L 的结果是出乎意料的。
  • 正确。我更新了关于演员的答案。是的,如果确实需要一个索引为 1 的序列,则需要 numb-1
  • 其实我刚刚更新了我的答案...你能看看第二种情况吗。
【解决方案2】:

如果由于某种原因您需要自己分配号码,因此无法使用 aioobe 的好解决方案,您可以执行以下操作:

public enum DataType {
    IMAGES(1),
    VIDEOS(2);

 private final int value;
 private DataType(int i){
    this.value=i;
 }
 public static DataType getByValue(int i) {
     for(DataType dt : DataType.values()) {
         if(dt.value == i) {
             return dt;
         }
     }
     throw new IllegalArgumentException("no datatype with " + i + " exists");
 }

静态方法getByValue() 使用提供的编号搜索DataType

【讨论】:

  • 我刚刚更新了我的问题。任何想法如何使它适用于第二种情况?
【解决方案3】:

除了@aioobe's answer,您还可以滚动自己的getInstance 方法。这将提供更大的灵活性,因为您不会依赖于序数。

public enum DataType {
    .
    .
    public static final DataType getInstance(final int i){
        for(DataType dt: DataType.values()){
            if(dt.value == i){
                return dt;
            }
        }

        return null;
    }
}

【讨论】:

    【解决方案4】:

    来自 aioobe 的正确答案。也许还有其他顾虑?

    对于枚举索引,最好使用 int 而不是 long。 可能是这样的:

    String indexAsString;
    int index = Integer.parseInt(indexAsString)-1;
    DataType dataType = DataType.values()[index];
    

    请注意“-1”,因为数组是从零开始的,而您的索引是从一开始的。

    【讨论】:

      【解决方案5】:

      如果您传递给枚举的数字是索引而不是一些任意代码,例如分辨率或一行中的字符数,则ordinal() 将起作用。

      我将使用值的访问器方法、分辨率索引和将数字解析为 Enum 值的静态方法来扩展枚举。给你...

      public enum DataType {
             IMAGES(1),
             VIDEOS(2);
          private int value;
      
          DataType(int i){
             this.value=i;
          }
      
          static final Map<Integer,DataType> inverseIndex;
          static {
              inverseIndex = new HashMap<Integer,DataType> ();
              for (DataType dt:DataType.values()) {
                  inverseIndex.put(dt.getValue(), dt);
              }   
          }
      
          public int getValue() {
              return value;
          }
      
          public static DataType resolve(int number) {
              return inverseIndex.get(number);
          }
      }
      

      请注意,此解决方案不起作用,因为您的地图枚举值不是双射的,因此您的 enumType 中的枚举可能只有不同的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-21
        • 1970-01-01
        • 2013-09-07
        相关资源
        最近更新 更多