1. Antecedentes sobre cómo enumsurgió

Hoy exploraremos otro tipo de tipo de datos en Java: enum. El nombre enumproviene de la palabra enumeración . ¿Qué es este tipo de datos y para qué sirve?

A veces, un programador necesita crear un nuevo tipo de datos, cuyos valores posibles se limitan a una pequeña lista fija.

Por ejemplo, un DayOfTheWeektipo solo puede tomar los valores MONDAY, TUESDAY, WEDNESDAY, ... Hay 7 valores en total. O un Monthtipo solo puede tomar los valores JANUARY, FEBRUARY, MARCH, ... Hay 12 valores en total.

Por supuesto, puede usar números (el inttipo): 1— lunes, 2— martes, etc. Pero alguien podría asignar accidentalmente valores no válidos como 8o 0a su variable.

Fácilmente podría tener una situación en la que un programador piense que los días de la semana (o los meses del año) se numeran a partir de cero, mientras que otros esperan que su numeración comience a partir de uno, etc.

Es por eso que introdujo Java enum, un tipo de datos que consta de un conjunto finito de valores .


2. Declarar un tipo

La declaración de un nuevo enumtipo de datos se ve así:

enum TypeName
{
   VALUE1,
   VALUE2,
   VALUE3
}

Donde TypeNamees el nombre del nuevo tipo (clase), y los posibles valores están separados por comas y encerrados entre llaves: Value1, Value2, Value3.

Como ejemplo, vamos a crear el nuestro propio DayOfTheWeek enum:

Código Nota
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY
}
Nuevo Daytipo

Lunes
Martes
Miércoles
Jueves
Viernes
Sábado
Domingo

Así es como se asigna un valor a una variable de nuestro nuevo tipo:

Day day = Day.MONDAY;

Ejemplo:

Código Nota
Day day = Day.FRIDAY;
System.out.println(day);
La salida de pantalla será:
FRIDAY


3. Métodos de unenum

Un enumtipo tiene varios métodos integrados, dos de los cuales son muy interesantes:

El método estático values()devuelve una matriz de todos los valores del enumtipo:

Código Nota
Day[] days = Day.values();

for (Day day: days)
   System.out.println(day);







System.out.println(days[2]);
La daysvariable almacena una matriz que contiene los valores del Daytipo (7 elementos)

Muestra el contenido de la matriz en la pantalla:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

WEDNESDAY

El ordinal()método devuelve el número ordinal de la constante. Lo llamas en un enumvalor en lugar de una enumclase:

Código Salida de consola
System.out.println(Day.MONDAY.ordinal());
System.out.println(Day.FRIDAY.ordinal());
System.out.println(Day.SUNDAY.ordinal());
0
4
6


4. Convertir a una clase

En realidad, no hay nada mágico aquí. El compilador nos acaba de dar algo de azúcar sintáctico. En tiempo de compilación, la Dayenumeración se convierte en una clase ordinaria:

Código, versión simplificada Nota
public class Day
{
   public static final Day MONDAY = new Day(0);
   public static final Day TUESDAY = new Day(1);
   public static final Day WEDNESDAY = new Day(2);
   public static final Day THURSDAY = new Day(3);
   public static final Day FRIDAY = new Day(4);
   public static final Day SATURDAY = new Day(5);
   public static final Day SUNDAY = new Day(6);

    private static final Day[] array = {MONDAY, TUESDAY,
      WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};

   private final int value;

   private Day (int value)
   {
      this.value = value;
   }

   public int ordinal()
   {
      return this.value;
   }

   public static Day[] values()
   {
      return array;
   }
}
Dayclase

Lista de constantes estáticas







Una matriz con todos los valores de la Dayenumeración


Una variable que almacena el valor de un Dayobjeto específico

La Dayclase constructores privada, lo que significa que los objetos de la Dayclase solo se pueden crear dentro de la Dayclase.



El ordinalmétodo debe ser llamado en un Dayobjeto.

Devuelve el valor del objeto: el valuecampo.


El método devuelve una matriz estática con todos los valores de la Dayclase .

Si eliminamos todos los métodos y variables estáticos de la Dayclase, obtenemos lo siguiente:

Código Nota
public class Day
{
  private int value;

  private Day (int value)
  {
    this.value = value;
  }

  public int ordinal()
  {
    return this.value;
  }
}


La valuevariable almacena el valor del Dayobjeto.

DayLos objetos solo se pueden crear dentro de la Dayclase, ya que el constructor es private.




El ordinal()método devuelve el valuedel Dayobjeto.

En otras palabras, nada aterrador está sucediendo aquí. El compilador crea la Dayclase, agrega las constantes que representan los enumvalores, agrega los métodos necesarios y crea el constructor de la clase private. Veremos cómo funcionan los constructores un poco más tarde.

Con suerte, ahora está claro por qué asignamos un valor a una variable de esta manera:

Day day = Day.MONDAY;

MONDAYes solo un campo estático (constante) en la Dayclase. Al acceder a métodos y campos estáticos desde fuera de la clase, debe indicar el nombre de la clase antes del nombre del campo o método.



5. Más métodos de unenum

Cada enumclase tiene varias características interesantes.

Convertir a y desde una cadena

Para convertir un objeto de enumeración en una cadena, debe llamar a su toString()método.

String str = Day.MONDAY.toString();

Para convertir en la otra dirección (de una cadena a un Dayobjeto), puede usar el valueOf()método estático:

Day day = Day.valueOf("MONDAY");

Es muy conveniente y será útil en muchos casos.

Convertir a un número y viceversa

Ya sabes cómo convertir un enumobjeto en un número: llama al ordinal()método:

int index = Day.MONDAY.ordinal();

Para convertir en la otra dirección (de un número a un Dayobjeto), necesita una construcción más transparente:

Day day = Day.values()[2];

Ejemplos:

Código Nota
Day day = Day.MONDAY;
int index = day.ordinal();
Day newDay = Day.values()[index+2];
Lunes
Obtener el índice del lunes: 0
Día de la semana 2 días después del lunes

Punto importante: debido a que enumlos valores son un conjunto fijo de constantes, se pueden comparar usando == . En otras palabras, no puede tener dos MONDAYobjetos idénticos con direcciones diferentes. Solo existe una única instancia de cada valor de enumeración. Y eso significa que comparar variables de enumeración usando == siempre funcionará.



6. Agregar sus propios métodos a unenum

Debido a que an enumse convierte en una clase ordinaria en tiempo de compilación, puede declarar métodos en ella. Estos métodos simplemente se agregan a la clase que genera el compilador. Por ejemplo, supongamos que queremos Day enumque devuelva una lista de valores de enumeración en lugar de una matriz.

Luego podemos agregar el siguiente código:

Código Nota
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY;

   public static List<Day> asList()
   {
      ArrayList<Day> list = new ArrayList<Day>();

      Collections.addAll(list, values());

      return list;
   }

}








Se requiere un punto y coma después de la lista de valores.



Crea un ArrayListobjeto

Agrega los valores en la matriz devuelta por el values()método.
Devuelve la lista.

Ahora este método se puede llamar en código:

Código Nota
List<Day> list = Day.asList();
La listvariable almacenará una lista de todos los valores de Day enum.