If you’ve found this post, chances are you want to convert from an enum to an int, or alternatively from an int to an enum in Java. Well… you can’t. Java has the most robust implementation of the ‘enum pattern’ of any language, in essence enums are a class that can only be instantiated once. This makes them ideal as singletons by the way…
Anyway, since enums are a class, you need to provide the int functionality yourself. For my example, I’m going to be making a ‘difficulty’ enum which should be very familiar with anyone making games for Android. First declare your enum:
public enum Difficulty { EASY(0), MEDIUM(1), HARD(2); /** * Value for this difficulty */ public final int Value; private Difficulty(int value) { Value = value; } }
This should be fairly familiar to you if you’ve worked with Java enums for any length of time. Each enum is effectively an instance of itself, so we can pass values to the constructor. We store the value in a final field (enums are by definition immutable – don’t go breaking this without good reason!) for future retrieval. Ideally the value should be accessed by a getter rather than directly, but I think in this case it makes more sense to making it a public field. The user can’t change it, and we don’t need any code to run on access; so I think a getter would just reduce performance and make consumption that little bit more tedious.
Now we need to add the important part, the conversion from int to the enum itself:
// Mapping difficulty to difficulty id private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>(); static { for (Difficulty difficulty : Difficulty.values()) _map.put(difficulty.Value, difficulty); } /** * Get difficulty from value * @param value Value * @return Difficulty */ public static Difficulty from(int value) { return _map.get(value); }
So what are we doing here, exactly? Well we create a map that will be our lookup table, we do this rather than a switch statement to minimise long-term maintenance. If someone added an extra enumeration in the future, they may forget to update the switch statement – and this error won’t be picked up until runtime, and even then it may appear as incorrect behaviour rather than throwing an exception. After we’ve created the map, we populate it automatically by looping through all of the enums and adding them and their value to the map.
So there you have it, the proper pattern for adding int values to an enumeration. The code in full is below:
public enum Difficulty { EASY(0), MEDIUM(1), HARD(2); /** * Value for this difficulty */ public final int Value; private Difficulty(int value) { Value = value; } // Mapping difficulty to difficulty id private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>(); static { for (Difficulty difficulty : Difficulty.values()) _map.put(difficulty.Value, difficulty); } /** * Get difficulty from value * @param value Value * @return Difficulty */ public static Difficulty from(int value) { return _map.get(value); } }
Bonus
OK I can’t leave you with just this without providing a little ‘from here’ info. Switching on an enum in Java isn’t ideal since you can add all sorts of information to the enum to minimise the necessity for a glorified if..elseif statement. For this difficulty example, we could add a ‘multiplier’ field that allows code to automatically modify state values based on the selected difficulty. See below:
public enum Difficulty { EASY(0, 0.5f), MEDIUM(1, 1.0f), HARD(2, 2.0f); /** * Value for this difficulty */ public final int Value; /** * Multiplier for difficulty */ public final float DifficultyMultiplier; private Difficulty(int value, float multiplier) { Value = value; DifficultyMultiplier = multiplier; } }
So now we’ve added the multiplier to the difficulty, we could use it like so:
enemy.speed = baseSpeed * difficulty.DifficultyMultiplier; player.speed = baseSpeed / difficulty.DifficultyMultiplier;
This has the added advantage that you can manipulate the global difficulty in a single central place.
Great post man. Enum in Java are great feature and most versatile and very useful under certain scenario. In my opinion following are some of benefits of enum in java :
1) Enum is type-safe you can not assign anything else other than predefined enum constant to an enum variable.
By the way I have also blogged my experience as 10 examples of enum in java , let me know how do you find it.
Fantastic article and great explanation, I like the bonus part, I would also like to share one link about enum in java
Fantastic article:)
Great article. Fantastic use of enums. I’ve always used enums with values, but I’ve had no good way of converting a value to its enum equivalent. This approach is simple and elegant.
Exactly what I need. Asking a bit more: I have about 50 enums I have to convert. Is there any way to put these functions in a generic or interface to avoid code duplication?
Well coming from a C# background I was trying to do something I use to do back in my C# days in Java and couldn’t turns out the implementations are different and C# offers a nice feature that you can declare an Enum that inherits from the Class Integer, something like:
public Enum Difficulty : Integer{
Easy=1,
Medium=2,
Hard=3
}
no need to use getters or setters, that in C# are called properties and then assigning the value from Difficulty.Easy to a Integer variable it’s transparent, there’s an automatic unboxing, If I recall correctly. You can simulate this effect with Java but it’s needs a little bit more of code.
“Well… you can’t. Java has the most robust implementation of the ‘enum pattern’ of any language”
Nope. Just a cave language that should be extincted.
Stop excusing it’s flaws.