4

I had a little problem with casting Java long type to Enum type and can't find a solution how to do that.

Here is what I'm using :

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

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

and I need to do something like this:

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

The error that I get says:

Convert numb to DataType or convert dataType to long.

Second Scenario:

I have this :

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.

I tried to convert thiz to String[] and use valueOf,but

Any suggestions how to get the thinks to work?

Thanks in advance!

Android-Droid
  • 14,365
  • 41
  • 114
  • 185

5 Answers5

11

Enum already provides a unique integer for each of it's instances. Check out ordinal(). (Note that it's zero-based though.)

If you need to go from a long to a DataType you can do

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

A complete list of conversions from and to enum constants, strings and integers can be found in this answer:

Community
  • 1
  • 1
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 3
    Having your own `id` for every enum constant is imho a good practise in scenarios where you have this IDs persisted, since `ordinal()` may change for the same item when you insert new constants in between. – Fabian Barney Aug 29 '11 at 13:07
  • To get rid of a warning, you should use a cast: `DataType.values ()[(int) numb];` and I guess VIDEOS as a result for 1L is unexpected. – user unknown Aug 29 '11 at 13:10
  • right. I updated the answer regarding the cast. Yes, if one indeed need a 1-indexed sequence, a `numb-1` is needed. – aioobe Aug 29 '11 at 13:20
  • Actually I just updated my answer...can you look at the second scenario. – Android-Droid Aug 29 '11 at 13:28
5

If for some reason you need to assign the numbers yourself and thereby can't use aioobe's good solution, you can do something like the following:

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");
 }

The static method getByValue() searches for the DataType with the provided number.

musiKk
  • 14,751
  • 4
  • 55
  • 82
5

In addition to @aioobe's answer, you could roll your own getInstance method. This would provide more flexibility, since you wouldn't be dependent on the ordinal.

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

        return null;
    }
}
Community
  • 1
  • 1
mre
  • 43,520
  • 33
  • 120
  • 170
2

Correct answer from aioobe. Maybe some other concerns ?

You could be better of using int instead of long, for the enum index. It could be like :

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

Please note the "-1", as arrays are zero-based while your index is one-based.

KLE
  • 23,689
  • 4
  • 56
  • 62
1

ordinal() will work if the numbers you are passing to the enum are indexes and not some arbitrary code, like resolution or number of chars in a line.

I'd extends the enum with an accesor method for the value, a resolution index and a static method that resolves a number into a Enum value. Here you go...

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);
    }
}

Note that this solution won't work is your map Enum-value is not bijective, so you may only have distinct values for the enums in your enumType.

maasg
  • 37,100
  • 11
  • 88
  • 115