I have this enum
:
enum class Types(val value: Int) {
FOO(1)
BAR(2)
FOO_BAR(3)
}
How do I create an instance of that enum
using an Int
?
I tried doing something like this:
val type = Types.valueOf(1)
And I get the error:
Integer literal does not conform to the expected type String
Enum#valueOf
is based on name. Which means in order to use that, you'd need to usevalueof("FOO")
. Thevalueof
method also takes a String, which explains the error. A String isn't an Int; types matter. The reason I mentioned what it does too, is so you know this isn't the method you're looking for.If you want to grab one based on an int value, you need to define your own function to do so. You can get the values in an enum using
values()
, which returns anArray<Types>
in this case. You can usefirstOrNull
as a safe approach, orfirst
if you prefer an exception over null.So add a companion object (which are static relative to the enum, so you can call
Types.getByValue(1234)
(Types.COMPANION.getByValue(1234)
from Java) overTypes.FOO.getByValue(1234)
.values()
returns a new Array every time it's called, which means you should cache it locally to avoid re-creating one every single time you callgetByValue
. If you callvalues()
when the method is called, you risk re-creating it repeatedly (depending on how many times you actually call it though), which is a waste of memory.The function could also be expanded and check based on multiple parameters, if that's something you want to do. These types of functions aren't limited to one argument.
Naming of the function is entirely up to you though. It doesn't have to be
getByValue
.If you are using integer value only to maintain order, which you need to access correct value, then you don't need any extra code. You can use build in value ordinal. Ordinal represents position of value in enum declaration.
Here is an example:
You can access ordinal value simply calling:
To get correct value of enum you can simply call:
Types.values() returns enum values in order accordingly to declaration.
Summary:
If integer values don't match order (int_value != enum.ordinal) or you are using different type (string, float...), than you need to iterate and compare your custom values as it was already mentioned in this thread.
I would build the 'reverse' map ahead of time. Probably not a big improvement, but also not much code.
Edit:
map
...toMap()
changed toassociate
per @hotkey's suggestion.A naive way can be:
Then you can use
try this...
You may want to add a safety check for the range and return null.