Java 43: Enums with Fields, Methods & EnumMap/EnumSet
easy⏱ 5 mincoursejava
Los enums llevan estado y comportamiento
Cada constante llama a un constructor privado con sus datos: MERCURY(3.3e23, 2.4e6). Añade campos final, un constructor y métodos accesores. Como cada constante es un singleton, == es seguro y rápido para comparar (no hace falta .equals()), y se usan naturalmente como etiquetas de switch.
enum Planet {
EARTH(5.976e24, 6.37e6),
MARS (6.42e23, 3.39e6);
private final double mass, radius;
Planet(double m, double r) { mass = m; radius = r; }
double gravity() { return 6.67e-11 * mass / (radius * radius); }
}
Cuerpos específicos por constante
Declara un método abstracto en el enum y sobreescríbelo por constante — cada constante se vuelve su propia instancia de subclase. Es un patrón strategy ordenado: Operation.PLUS.apply(2, 3) despacha al cuerpo de PLUS. Sin switch, sin bugs de fall-through, exhaustivo por construcción.
enum Op {
PLUS { int apply(int a, int b) { return a + b; } },
TIMES { int apply(int a, int b) { return a * b; } };
abstract int apply(int a, int b);
}
EnumSet y EnumMap
EnumSet es un Set implementado como vector de bits — EnumSet.of(MON, FRI) es un único long para ≤64 constantes, haciendo contains/add O(1) y diminuto. EnumMap es un Map respaldado por un arreglo indexado por ordinal() — más rápido y denso que HashMap para claves enum, con orden de iteración predecible (de declaración). Prefiere ambos sobre las colecciones genéricas cuando las claves son constantes enum.
Construye un enum de gravedad + EnumMap
Modela las constantes Planet con masa+radio y un método gravity() (G = 6.67e-11). Calcula el peso de un humano de 75kg en cada planeta (masa * gravedad). Luego construye un enumMap (Map por nombre de planeta, iterado en orden de declaración) de planeta -> peso, y un enumSet de los planetas de 'baja gravedad' donde gravedad < la de la Tierra. Imprime ambos.
Nunca persistas ordinal()
ordinal() devuelve el índice de declaración — pero cambia en el momento en que alguien reordena o inserta una constante, corrompiendo en silencio datos guardados. Persiste el nombre (name() / valueOf) o un campo de código estable explícito. ordinal() está bien para los internos de EnumMap/EnumSet en memoria, nunca para serialización.
Quiz: singleton de enum y threads
¿Por qué un enum de una sola constante es el Singleton recomendado en Java? La JVM garantiza que cada constante enum se instancia exactamente una vez, de forma lazy y thread-safe, y es a prueba de serialización (ni reflection ni clone pueden duplicarla). El Effective Java de Joshua Bloch lo llama la mejor implementación de singleton.