Obtener enum por su campo interno

Tener enum con campos internos, tipo de mapa.

Ahora necesito entrar enum por su campo interno.

Escribí esto:

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; } } 

Pero no es muy eficiente buscar en todas las enumeraciones cada vez que necesito encontrar una instancia apropiada.

¿Hay alguna otra manera de hacer lo mismo?

Puede usar un static Map con un inicializador static que lo llena con los valores de TestEnum marcados por sus campos number .

Tenga en cuenta que findByKey se ha convertido en static , y el number también se ha hecho 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 map; static { map = new HashMap(); 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" } } 

Ahora puede esperar que findByKey sea ​​una operación O(1) .

Referencias

  • Inicializadores estáticos JLS 8.7
  • JLS 8.9 Enums

Preguntas relacionadas

  • Initizador estático en Java
  • Cómo inicializar un mapa estático en Java

Nota sobre los values()

La segunda instrucción println en el método main es reveladora: values() devuelve una matriz recién asignada con cada invocación. La solución original O(N) podría mejorar un poco llamando solo a values() una vez y almacenando en caché la matriz, pero esa solución aún sería O(N) en promedio.

Aunque alguien ha sugerido usar Map pensarlo dos veces.

Su solución original, especialmente para enumeraciones pequeñas, puede ser mucho más rápida que usar HashMap.

HashMap probablemente no sea más rápido hasta que tu enumeración contenga al menos de 30 a 40 elementos.

Este es un caso de “Si no está roto, no lo arregles”.

Debería tener un HashMap con los números como claves y los valores enum como valores.

Este mapa generalmente puede estar en su repository. Luego puede reemplazar fácilmente una variable int de la base de datos con su valor enum preferido.

Si sus claves (valores int) están almacenadas en una base de datos, entonces diré que es un mal diseño para llevar esas claves en una enumeración en su capa de negocios. Si ese es el caso, recomendaré no almacenar el valor int en la enumeración.

Una solución es agregar

 public final Test[] TESTS = { null, ONE, TWO, THREE }; public static Test getByNumber(int i) { return TESTS[i]; } 

A la enum.

Si los datos internos no son un número entero, puede tener un Mapa que rellene en un inicializador static { ... } . Este mapa podría usarse luego en el método getByNumber anterior.