Enums en Java
Constantes tipadas, métodos y uso avanzado
Enum básico
Un enum en Java es una clase especial que tiene un número fijo de instancias predefinidas, llamadas
constantes. Cada constante es un singleton de la clase enum. Son preferibles a las constantes static final int porque el compilador verifica que solo se usen valores válidos del enum.
// Enum básico: constantes tipadas
public enum DiaSemana {
LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
}
DiaSemana hoy = DiaSemana.LUNES;
// Métodos heredados de Enum
String nombre = hoy.name(); // "LUNES"
int posicion = hoy.ordinal(); // 0 (posición en la declaración)
// Comparación: == es válido para enums (son singletons)
if (hoy == DiaSemana.LUNES) System.out.println("Inicio de semana");
// Convertir String a enum
DiaSemana dia = DiaSemana.valueOf("MARTES"); // DiaSemana.MARTES
// IllegalArgumentException si el nombre no existe
// Todos los valores
DiaSemana[] todos = DiaSemana.values(); Enums con campos y métodos
Los enums pueden tener campos, constructores (privados) y métodos como cualquier clase. Cada constante puede recibir argumentos en su declaración. Esto permite asociar datos y comportamiento a cada valor del enum de forma limpia.
// Enums con campos, constructor y métodos
public enum Planeta {
MERCURIO(3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
TIERRA (5.976e+24, 6.37814e6),
MARTE (6.421e+23, 3.3972e6);
private final double masa; // kg
private final double radio; // metros
Planeta(double masa, double radio) {
this.masa = masa;
this.radio = radio;
}
static final double G = 6.67300E-11;
double gravedadSuperficial() {
return G * masa / (radio * radio);
}
double pesoEn(double pesoEnTierra) {
return pesoEnTierra * gravedadSuperficial() / TIERRA.gravedadSuperficial();
}
}
double pesoEnMarte = Planeta.MARTE.pesoEn(75.0); // kg Comportamiento por constante
Cada constante de un enum puede tener su propia implementación de un método abstracto. Este patrón es una
alternativa limpia a los switch o if-else
basados en constantes — el comportamiento está encapsulado junto al valor.
// Enum con métodos abstractos: cada constante implementa su propio comportamiento
public enum Operacion {
SUMA("+") {
@Override
public double aplicar(double a, double b) { return a + b; }
},
RESTA("-") {
@Override
public double aplicar(double a, double b) { return a - b; }
},
MULTIPLICACION("*") {
@Override
public double aplicar(double a, double b) { return a * b; }
};
private final String simbolo;
Operacion(String simbolo) { this.simbolo = simbolo; }
public abstract double aplicar(double a, double b);
@Override
public String toString() { return simbolo; }
}
// Uso:
for (Operacion op : Operacion.values()) {
System.out.printf("10 %s 3 = %.1f%n", op, op.aplicar(10, 3));
} EnumSet y EnumMap
Cuando se trabaja con colecciones de enums, EnumSet y EnumMap
son significativamente más eficientes que HashSet y HashMap. Internamente usan
representación de bits.
// EnumSet y EnumMap: implementaciones optimizadas para enums
import java.util.EnumSet;
import java.util.EnumMap;
// EnumSet: Set muy eficiente basado en bits (un long puede representar 64 constantes)
EnumSet<DiaSemana> laborables = EnumSet.range(DiaSemana.LUNES, DiaSemana.VIERNES);
EnumSet<DiaSemana> finde = EnumSet.of(DiaSemana.SABADO, DiaSemana.DOMINGO);
EnumSet<DiaSemana> todos = EnumSet.allOf(DiaSemana.class);
// EnumMap: Map con claves enum, más eficiente que HashMap para este caso
EnumMap<DiaSemana, String> horario = new EnumMap<>(DiaSemana.class);
horario.put(DiaSemana.LUNES, "09:00-18:00");
horario.put(DiaSemana.SABADO, "cerrado");