Have enum with inner fields, kind of map.
Now I need to get enum by its inner field.
Wrote this:
package test; /** * Test enum to test enum =) */ public enum TestEnum { ONE(1), TWO(2), THREE(3); private int number; TestEnum(int number) { this.number = number; } public TestEnum findByKey(int i) { TestEnum[] testEnums = TestEnum.values(); for (TestEnum testEnum : testEnums) { if (testEnum.number == i) { return testEnum; } } return null; } }
But it's not very efficient to look up through all enums each time I need to find appropriate instance.
Is there any other way to do the same?
Example: Lookup enum by string value We then use the enum TextStyle's valueOf() method to pass the style and get the enum value we require. Since valueOf() takes a case-sensitive string value, we had to use the toUpperCase() method to convert the given string to upper case.
An enum is a special "class" that represents a group of constants (unchangeable variables, like final variables). To create an enum , use the enum keyword (instead of class or interface), and separate the constants with a comma.
valueOf. Returns the enum constant of the specified enum type with the specified name. The name must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)
You can use a static Map<Integer,TestEnum>
with a static
initializer that populates it with the TestEnum
values keyed by their number
fields.
Note that findByKey
has been made static
, and number
has also been made final
.
import java.util.*; public enum TestEnum { ONE(1), TWO(2), SIXTY_NINE(69); private final int number; TestEnum(int number) { this.number = number; } private static final Map<Integer,TestEnum> map; static { map = new HashMap<Integer,TestEnum>(); for (TestEnum v : TestEnum.values()) { map.put(v.number, v); } } public static TestEnum findByKey(int i) { return map.get(i); } public static void main(String[] args) { System.out.println(TestEnum.findByKey(69)); // prints "SIXTY_NINE" System.out.println( TestEnum.values() == TestEnum.values() ); // prints "false" } }
You can now expect findByKey
to be a O(1)
operation.
values()
The second println
statement in the main
method is revealing: values()
returns a newly allocated array with every invokation! The original O(N)
solution could do a little better by only calling values()
once and caching the array, but that solution would still be O(N)
on average.
Although someone has suggested using Map<Integer, TestEnum>
think twice about it.
Your original solution, especially for small enums, may be magnitudes faster than using HashMap.
HashMap will probably be not faster until your enum contains at least 30 to 40 elements.
This is one case of "If it ain't broken, don't fix it".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With