1. Bakgrund om hur enumkom till

Idag ska vi utforska en annan typ av datatyp i Java: enum. Namnet enumkommer från ordet uppräkning . Vad är denna datatyp och vad är den till för?

Ibland behöver en programmerare skapa en ny datatyp, vars möjliga värden är begränsade till en liten fast lista.

Till exempel DayOfTheWeekkan en typ bara ta värdena , MONDAY, TUESDAY, WEDNESDAY... Det finns 7 värden totalt. Eller en Monthtyp kan bara ta värdena , , JANUARY, FEBRUARY... MARCHDet finns totalt 12 värden.

Naturligtvis använder du kundenummer (typen int): 1— Måndag, 2— Tisdag, etc. Men någon kan av misstag tilldela ogiltiga värden som 8eller 0till din variabel.

Du kan lätt ha en situation där en programmerare tror att veckodagarna (eller månaderna på året) är numrerade från noll, medan andra förväntar sig att deras numrering börjar från ett, etc.

Det är därför Java introducerade enum, en datatyp som består av en ändlig uppsättning värden .


2. Deklarera en typ

Att deklarera en ny enumdatatyp ser ut så här:

enum TypeName
{
   VALUE1,
   VALUE2,
   VALUE3
}

Var TypeNameär namnet på den nya typen (klassen), och de möjliga värdena är separerade med kommatecken och inslagna i hängslen: Value1, Value2, Value3.

Som ett exempel, låt oss skapa vår egen DayOfTheWeek enum:

Koda Notera
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY
}
Ny Daytyp

måndag tisdag
onsdag
torsdag
fredag
​​lördag
söndag

Så här tilldelar du ett värde till en variabel av vår nya typ:

Day day = Day.MONDAY;

Exempel:

Koda Notera
Day day = Day.FRIDAY;
System.out.println(day);
Skärmutgången blir:
FRIDAY


3. Metoder för enenum

En enumtyp har flera inbyggda metoder, varav två är mycket intressanta:

Den statiska values()metoden returnerar en matris med alla värden av enumtypen:

Koda Notera
Day[] days = Day.values();

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







System.out.println(days[2]);
Variabeln dayslagrar en array som innehåller värdena av Daytypen (7 element)

Visa innehållet i arrayen på skärmen:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

WEDNESDAY

Metoden ordinal()returnerar ordningstalet för konstanten. Du kallar det för ett enumvärde snarare än en enumklass:

Koda Konsolutgång
System.out.println(Day.MONDAY.ordinal());
System.out.println(Day.FRIDAY.ordinal());
System.out.println(Day.SUNDAY.ordinal());
0
4
6


4. Konvertera till en klass

I verkligheten finns det inget magiskt här. Kompilatorn gav oss bara lite syntaktisk socker. Vid kompilering Daykonverteras enumen till en vanlig klass:

Kod, förenklad version Notera
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

Lista över statiska konstanter







En array med alla värden av Dayenum


En variabel som lagrar värdet på ett specifikt Dayobjekt

Klassens är privat, vilket innebär att objekt i Dayklassen endast kan skapas inuti klassen . Metoden måste anropas på ett objekt. Det returnerar objektets värde - fältet . Metoden returnerar en statisk array med alla värden för klassenconstructorDayDay



ordinalDay

value


Day

Om vi ​​tar bort alla statiska metoder och variabler från klassen Dayfår vi följande:

Koda Notera
public class Day
{
  private int value;

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

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


Variabeln valuelagrar värdet på Dayobjektobjekten

Daykan bara skapas i Dayklassen, eftersom konstruktorn är private.




Metoden ordinal()returnerar valueobjektets Day.

Här händer med andra ord inget läskigt. Kompilatorn skapar Dayklassen, lägger till konstanterna som representerar enumvärdena, lägger till de nödvändiga metoderna och gör klasskonstruktorn private. Vi ska titta på hur konstruktörer fungerar lite senare.

Förhoppningsvis är det nu klart varför vi tilldelar ett värde till en variabel på det här sättet:

Day day = Day.MONDAY;

MONDAYär bara ett statiskt fält (konstant) i Dayklassen. När du kommer åt statiska metoder och fält utanför klassen måste du ange klassnamnet före namnet på fältet eller metoden.



5. Fler metoder för enenum

Varje enumklass har flera intressanta funktioner.

Konvertera till och från en sträng

För att konvertera ett enum-objekt till en sträng måste du anropa dess toString()metod.

String str = Day.MONDAY.toString();

För att konvertera i den andra riktningen (från en sträng till ett Dayobjekt) kan du använda den statiska valueOf()metoden:

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

Det är superbekvämt och kommer att vara till hjälp i många fall.

Konverterar till ett nummer och tillbaka igen

Du vet redan hur man konverterar ett enumobjekt till ett tal: anrop ordinal()metoden:

int index = Day.MONDAY.ordinal();

För att konvertera i den andra riktningen (från ett tal till ett Dayobjekt) behöver du en mer transparent konstruktion:

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

Exempel:

Koda Notera
Day day = Day.MONDAY;
int index = day.ordinal();
Day newDay = Day.values()[index+2];
Måndag
Hämta index för måndag: 0
Veckodag 2 dagar efter måndag

Viktig punkt: eftersom enumvärden är en fast uppsättning konstanter kan de jämföras med == . Du kan med andra ord inte ha två identiska MONDAYobjekt med olika adress. Endast en enda instans av varje enumvärde finns. Och det betyder att jämföra enumvariabler med == alltid kommer att fungera.



6. Lägga till dina egna metoder till enenum

Eftersom en enumförvandlas till en vanlig klass vid kompilering, kan du deklarera metoder i den. Dessa metoder läggs helt enkelt till i klassen som kompilatorn genererar. Anta till exempel att vi vill att vi Day enumska returnera en lista med enumvärden snarare än en matris.

Sedan kan vi lägga till följande kod:

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

}








Ett semikolon krävs efter värdelistan.



Skapa ett ArrayListobjekt

Lägg till värdena i arrayen som returneras av values()metoden.
Lämna tillbaka listan.

Nu kan denna metod anropas i kod:

Koda Notera
List<Day> list = Day.asList();
Variabeln listlagrar en lista över alla värden för Day enum.