Pridavanje vrijednosti Java Enumu

1. Uvod

Java nabrajanje type pruža jezik podržani način stvaranja i korištenja konstantnih vrijednosti. Definiranjem konačnog skupa vrijednosti, nabrajanje je sigurniji za tip od konstantnih doslovnih varijabli poput Niz ili int.

Međutim, nabrajanje vrijednosti moraju biti valjani identifikatori, a mi se potičemo na upotrebu SCREAMING_SNAKE_CASE po dogovoru.

S obzirom na ta ograničenja, the nabrajanje vrijednost sama po sebi nije prikladna za nizove koji se mogu čitati čovjeku ili vrijednosti koje nisu niz.

U ovom uputstvu koristit ćemo nabrajanjeIma funkciju Java klase za pridruživanje vrijednosti koje želimo.

2. Korištenje Jave Enum kao Razred

Često stvaramo nabrajanje kao jednostavan popis vrijednosti. Na primjer, ovdje su jednostavna prva dva retka periodnog sustava nabrajanje:

javni popisni element {H, HE, LI, BE, B, C, N, O, F, NE}

Koristeći gornju sintaksu, stvorili smo deset statičnih, posljednjih instanci nabrajanje imenovan Element. Iako je ovo vrlo učinkovito, uhvatili smo samo simbole elemenata. I dok je oblik velikog slova prikladan za Java konstante, nije kako mi obično pišemo simbole.

Nadalje, nedostaju nam i druga svojstva elemenata periodnog sustava, poput imena i atomske težine.

iako nabrajanje type ima posebno ponašanje u Javi, možemo dodati konstruktore, polja i metode kao što to činimo s drugim klasama. Zbog toga možemo poboljšati svoje nabrajanje uključiti vrijednosti koje su nam potrebne.

3. Dodavanje konstruktora i završnog polja

Počnimo s dodavanjem imena elemenata. Imena ćemo postaviti u konačni varijabla pomoću konstruktora:

javni enum Element {H ("Vodik"), HE ("Helij"), // ... NE ("Neon"); javna konačna naljepnica; privatni element (oznaka niza) {this.label = label; }}

Prije svega, primjećujemo posebnu sintaksu na popisu deklaracija. Na ovaj se način poziva konstruktor nabrajanje vrste. Iako je ilegalno koristiti novi operator za nabrajanje, možemo proslijediti argumente konstruktora na popis deklaracije.

Zatim deklariramo varijablu instance označiti. O tome treba napomenuti nekoliko stvari.

Prvo smo odabrali označiti identifikator umjesto Ime. Iako polje člana Ime je dostupan za upotrebu, birajmo označiti kako bi se izbjegla zabuna s unaprijed definiranim Enum.name () metoda.

Drugo, naše označiti polje je konačni. Dok polja an nabrajanje ne moraju biti konačni, u većini slučajeva ne želimo da se naše etikete mijenjaju. U duhu nabrajanje vrijednosti su konstantne, to ima smisla.

Napokon, označiti polje je javno. Stoga naljepnici možemo pristupiti izravno:

System.out.println (BE.label);

S druge strane, polje može biti privatni, pristupljeno s getLabel () metoda. U svrhu kratkoće, ovaj će se članak i dalje koristiti stilom javnog polja.

4. Lociranje Jave Enum Vrijednosti

Java pruža a valueOf (String) metoda za sve nabrajanje vrste. Dakle, uvijek možemo dobiti nabrajanje vrijednost temeljena na deklariranom imenu:

assertSame (Element.LI, Element.valueOf ("LI"));

Međutim, možda bismo htjeli potražiti nabrajanje vrijednost i našim poljem oznaka. Da bismo to učinili možemo dodati a statički metoda:

javni statički Element valueOfLabel (Oznaka niza) {for (Element e: values ​​()) {if (e.label.equals (label)) {return e; }} return null; }

Statički valueOfLabel () metoda ponavlja it Element vrijednosti dok ne pronađe podudaranje. Vraća se null ako se ne pronađe podudaranje. Suprotno tome, izuzetak bi se mogao baciti umjesto da se vrati null.

Pogledajmo brzi primjer koristeći naš valueOfLabel () metoda:

assertSame (Element.LI, Element.valueOfLabel ("Litij"));

5. Keširanje vrijednosti pretraživanja

Možemo izbjeći ponavljanje nabrajanje vrijednosti pomoću a Karta za predmemoriranje naljepnica. Da bismo to učinili, definiramo a statička konačna karta i popunite ga kad se učita klasa:

public enum Element {// ... enum vrijednosti private static final Map BY_LABEL = new HashMap (); static {for (Element e: values ​​()) {BY_LABEL.put (e.label, e); }} // ... polja, konstruktor, metode public static Element valueOfLabel (String label) {return BY_LABEL.get (label); }}

Kao rezultat predmemoriranja, nabrajanje vrijednosti se ponavljaju samo jednom, i valueOfLabel () metoda je pojednostavljena.

Kao alternativu, možemo lijeno konstruirati predmemoriju kada joj se prvi put pristupa u valueOfLabel () metoda. U tom se slučaju pristup mapi mora sinkronizirati kako bi se spriječili problemi s istodobnošću.

6. Priključivanje više vrijednosti

The Enum konstruktor može prihvatiti više vrijednosti. Za ilustraciju, dodajte atomski broj kao int a atomska težina kao a plutati:

javni enum Element {H ("Vodik", 1, 1.008f), HE ("Helij", 2, 4.0026f), // ... NE ("Neon", 10, 20.180f); privatna statička konačna karta BY_LABEL = nova HashMap (); privatna statička konačna karta BY_ATOMIC_NUMBER = nova HashMap (); privatna statička konačna karta BY_ATOMIC_WEIGHT = nova HashMap (); static {for (Element e: values ​​()) {BY_LABEL.put (e.label, e); BY_ATOMIC_NUMBER.put (e.atomicNumber, e); BY_ATOMIC_WEIGHT.put (e.atomicWeight, e); }} javna konačna oznaka niza; javni konačni int atomicNumber; javni konačni plutajući atomicWeight; private Element (oznaka niza, int atomicNumber, float atomicWeight) {this.label = label; this.atomicNumber = atomskiBroj; this.atomicWeight = atomskaTežina; } javni statički element valueOfLabel (oznaka niza) {return BY_LABEL.get (label); } javni statički element valueOfAtomicNumber (int broj) {return BY_ATOMIC_NUMBER.get (broj); } javni statički element valueOfAtomicWeight (plutajuća težina) {return BY_ATOMIC_WEIGHT.get (weight); }}

Slično tome, možemo dodati sve vrijednosti koje želimo u nabrajanje, kao što su odgovarajući simboli padeža, na primjer "He", "Li" i "Be".

Štoviše, možemo dodati izračunate vrijednosti u naš nabrajanje dodavanjem metoda za izvođenje operacija.

7. Kontrola sučelja

Kao rezultat dodavanja polja i metoda u naš nabrajanje, promijenili smo njegovo javno sučelje. Stoga je naš kod koji koristi jezgru EnumIme() i vrijednost() metode, neće biti svjesni naših novih polja.

The statičkivrijednost() metodu već nam je definirao jezik Java. Stoga ne možemo pružiti svoje vrijednost() provedba.

Slično tome, jer Enum.name () metoda je konačni, ni to ne možemo nadjačati.

Kao rezultat, ne postoji praktičan način da se naša dodatna polja koriste standardom Enum API. Umjesto toga, pogledajmo nekoliko različitih načina da izložimo svoja polja.

7.1. Nadjačavanje toString ()

Nadjačavanje toString () može biti alternativa nadjačavanju Ime():

@Override public String toString () {return this.label; }

Prema zadanim postavkama, Enum.toString () vraća istu vrijednost kao Enum.name ().

7.2. Implementacija sučelja

The nabrajanje tipa u Javi može implementirati sučelja. Iako ovaj pristup nije toliko generičan kao Enum API, sučelja nam pomažu u generaliziranju.

Razmotrimo ovo sučelje:

javno sučelje Označeno {Oznaka niza (); }

Radi dosljednosti s Enum.name () metoda, naša označiti() metoda nema a dobiti prefiks.

I, zato što valueOfLabel () metoda je statički, ne uključujemo ga u naše sučelje.

Konačno, sučelje možemo implementirati u naš nabrajanje:

public enum Element implementira Označeno {// ... @Preuzmi javni string label () {return label; } // ...}

Jedna od prednosti ovog pristupa je što Označen sučelje se može primijeniti na bilo koju klasu, ne samo nabrajanje vrste. Umjesto da se oslanjamo na generički Enum API, sada imamo API specifičniji za kontekst.

8. Zaključak

U ovom smo članku istražili mnoge značajke Jave Enum provedba. Dodavanjem konstruktora, polja i metoda, vidimo da nabrajanje može puno više od doslovnih konstanti.

Kao i uvijek, puni izvorni kod za ovaj članak nalazi se na GitHubu.