Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get enum by its inner field

Tags:

java

enums

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?

like image 450
zeroed Avatar asked May 06 '10 09:05

zeroed


People also ask

How can I lookup a Java enum from its string value?

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.

What is enumerations in Java?

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.

What does enum valueOf return?

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.)


2 Answers

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.

References

  • JLS 8.7 Static initializers
  • JLS 8.9 Enums

Related questions

  • Static initalizer in Java
  • How to Initialise a static Map in Java

Note on 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.

like image 84
polygenelubricants Avatar answered Oct 14 '22 04:10

polygenelubricants


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".

like image 42
Alexander Pogrebnyak Avatar answered Oct 14 '22 04:10

Alexander Pogrebnyak