1. Context despre cum enuma apărut

Astăzi vom explora un alt tip de tip de date în Java: enum. Numele enumprovine de la cuvântul enumerare . Ce este acest tip de date și pentru ce este?

Uneori, un programator trebuie să creeze un nou tip de date, ale cărui valori posibile sunt limitate la o mică listă fixă.

De exemplu, un DayOfTheWeektip poate lua numai valorile MONDAY, TUESDAY, WEDNESDAY, ... Există 7 valori în total. Sau un Monthtip poate lua numai valorile JANUARY, FEBRUARY, MARCH, ... Există 12 valori în total.

Desigur, folosiți numerele pot (tipul int): 1— luni, 2— marți, etc. Dar cineva ar putea atribui accidental valori nevalide, cum ar fi 8sau 0variabilei dvs.

Ați putea avea cu ușurință o situație în care un programator crede că zilele săptămânii (sau lunile anului) sunt numerotate începând de la zero, în timp ce alții se așteaptă ca numerotarea lor să înceapă de la unu etc.

De aceea enum, Java a introdus un tip de date care constă dintr -un set finit de valori .


2. Declararea unui tip

Declararea unui nou enumtip de date arată astfel:

enum TypeName
{
   VALUE1,
   VALUE2,
   VALUE3
}

Unde TypeNameeste numele noului tip (clasa), iar valorile posibile sunt separate prin virgule și înfășurate în acolade: Value1, Value2, Value3.

De exemplu, să ne creăm propriul DayOfTheWeek enum:

Cod Notă
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY
}
DayTip nou

Luni
Marti
Miercuri
Joi
Vineri Sambata
Duminica

Iată cum atribuiți o valoare unei variabile de noul nostru tip:

Day day = Day.MONDAY;

Exemplu:

Cod Notă
Day day = Day.FRIDAY;
System.out.println(day);
Ieșirea ecranului va fi:
FRIDAY


3. Metode de anenum

Un enumtip are mai multe metode încorporate, dintre care două sunt foarte interesante:

Metoda statică values()returnează o matrice cu toate valorile tipului enum:

Cod Notă
Day[] days = Day.values();

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







System.out.println(days[2]);
Variabila daysstochează o matrice care conține valorile tipului Day(7 elemente)

Afișează conținutul matricei pe ecran:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

WEDNESDAY

Metoda ordinal()returnează numărul ordinal al constantei. Îl numești pe o enumvaloare mai degrabă decât pe o enumclasă:

Cod Ieșire de consolă
System.out.println(Day.MONDAY.ordinal());
System.out.println(Day.FRIDAY.ordinal());
System.out.println(Day.SUNDAY.ordinal());
0
4
6


4. Convertirea într-o clasă

În realitate, nu este nimic magic aici. Compilatorul ne-a dat niște zahăr sintactic. La compilare, Dayenumerarea este convertită într-o clasă obișnuită:

Cod, versiune simplificată Notă
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;
   }
}
Dayclass

Listă de constante statice







Un tablou cu toate valorile enumerarii DayO


variabilă care stochează valoarea unui anumit Dayobiect

Clasa este privată, ceea ce înseamnă că obiectele clasei Daypot fi create numai în interiorul clasei . Metoda trebuie apelată pe un obiect. Returnează valoarea obiectului - câmpul . Metoda returnează un tablou static cu toate valorile claseiconstructorDayDay



ordinalDay

value


Day

Dacă eliminăm toate metodele și variabilele statice din Dayclasă, obținem următoarele:

Cod Notă
public class Day
{
  private int value;

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

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


Variabila valuestochează valoarea obiectelor Dayobiect

Daypoate fi creată numai în interiorul Dayclasei, deoarece constructorul este private.




Metoda ordinal()returnează valueobiectul Day.

Cu alte cuvinte, nu se întâmplă nimic înfricoșător aici. Compilatorul creează Dayclasa, adaugă constantele care reprezintă valorile enum, adaugă metodele necesare și face constructorul clasei private. Ne vom uita la modul în care lucrează constructorii puțin mai târziu.

Sperăm că acum este clar de ce atribuim o valoare unei variabile în acest fel:

Day day = Day.MONDAY;

MONDAYeste doar un câmp static (constant) în Dayclasă. Când accesați metode și câmpuri statice din afara clasei, trebuie să indicați numele clasei înaintea numelui câmpului sau metodei.



5. Mai multe metode de anenum

Fiecare enumclasă are câteva caracteristici interesante.

Conversia la și de la un șir

Pentru a converti un obiect enumerare într-un șir, trebuie să apelați toString()metoda acestuia.

String str = Day.MONDAY.toString();

Pentru a converti în cealaltă direcție (de la un șir la un Dayobiect), puteți utiliza valueOf()metoda statică:

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

Este foarte convenabil și va fi de ajutor în multe cazuri.

Convertirea într-un număr și înapoi din nou

Știți deja cum să convertiți un enumobiect într-un număr: apelați ordinal()metoda:

int index = Day.MONDAY.ordinal();

Pentru a converti în cealaltă direcție (de la un număr la un Dayobiect), aveți nevoie de o construcție mai transparentă:

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

Exemple:

Cod Notă
Day day = Day.MONDAY;
int index = day.ordinal();
Day newDay = Day.values()[index+2];
Luni
Obține indexul lunii: 0
Ziua săptămânii la 2 zile după luni

Punct important: deoarece enumvalorile sunt un set fix de constante, ele pot fi comparate folosind == . Cu alte cuvinte, nu poți avea două MONDAYobiecte identice cu adresă diferită. Există doar o singură instanță a fiecărei valori de enumerare. Și asta înseamnă că compararea variabilelor enumerate folosind == va funcționa întotdeauna.



6. Adăugarea propriilor metode la unenum

Deoarece an enumse transformă într-o clasă obișnuită în timpul compilării, puteți declara metode în ea. Aceste metode sunt pur și simplu adăugate la clasa pe care o generează compilatorul. De exemplu, să presupunem că vrem Day enumsă returnăm o listă cu valorile enumerate mai degrabă decât o matrice.

Apoi putem adăuga următorul cod:

Cod Notă
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;
   }

}








Este necesar un punct și virgulă după lista de valori.



Creați un ArrayListobiect

Adăugați valorile din tabloul returnat de values()metodă.
Întoarce lista.

Acum această metodă poate fi apelată în cod:

Cod Notă
List<Day> list = Day.asList();
Variabila listva stoca o listă cu toate valorile Day enum.