Get enum by its inner field

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


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.

Tags:

Java

Enums