Sprievodca po EnumSet

1. Úvod

V tomto výučbe sa pozrieme na EnumSet zbierka z java.util balíka a prediskutovať jeho zvláštnosti.

Najskôr si ukážeme hlavné rysy zbierky a potom si prejdeme vnútorné časti triedy, aby sme pochopili jej výhody.

Na záver sa budeme venovať hlavným operáciám, ktoré poskytuje, a implementujeme niekoľko základných príkladov.

2. Čo je to EnumSet

An EnumSet je špecializovaný Nastaviť zbierka na prácu enum triedy. Vykonáva Nastaviť rozhranie a siaha od Sada abstraktov:

Aj napriek tomu Sada abstraktov a AbstractCollection poskytuje implementácie pre takmer všetky metódy systému Nastaviť a Zbierka rozhrania, EnumSet prevažuje nad väčšinou z nich.

Keď plánujeme použiť EnumSet musíme vziať do úvahy niekoľko dôležitých bodov:

  • Môže obsahovať iba enum hodnoty a všetky hodnoty musia patriť k tomu istému enum
  • Neumožňuje pridávať nulové hodnoty, hádzanie a NullPointerException pri pokuse o to
  • Nie je to bezpečné pre vlákna, takže v prípade potreby ju musíme externe synchronizovať
  • Prvky sa ukladajú v poradí, v akom sú deklarované v enum
  • Používa bezpečnostný iterátor ktorý funguje na kópii, takže nebude hádzať a ConcurrentModificationException ak je kolekcia pri iterácii upravená

3. Prečo používať EnumSet

Ako všeobecné pravidlo EnumSet by mali byť vždy uprednostňované pred ostatnými Nastaviť implementáciu, keď ukladáme enum hodnoty.

V ďalších častiach uvidíme, čo robí túto zbierku lepšou ako ostatné. Za týmto účelom stručne ukážeme interné prvky triedy, aby sme lepšie porozumeli.

3.1. Podrobnosti implementácie

EnumSet je a verejnéabstraktné trieda, ktorá obsahuje niekoľko statických továrenských metód, ktoré nám umožňujú vytvárať inštancie. JDK poskytuje 2 rôzne implementácie - sú balík-súkromné a podporené bitovým vektorom:

  • RegularEnumSet a
  • JumboEnumSet

RegularEnumSet používa singel dlho reprezentovať bitový vektor. Každý bit z dlho prvok predstavuje hodnotu prvku enum. I-ta hodnota výčtu bude uložená v i-tom bite, takže je celkom ľahké zistiť, či je alebo nie je hodnota k dispozícii. Odkedy dlho je 64-bitový dátový typ, môže táto implementácia uložiť až 64 prvkov.

Na druhej strane, JumboEnumSet používa pole dlho prvky ako bitový vektor.Toto umožňuje tejto implementácii uložiť viac ako 64 prvkov. Funguje to podobne ako RegularEnumSet ale urobiť nejaké ďalšie výpočty na nájdenie indexu poľa, kde je uložená hodnota.

Nie je prekvapením, že prvý dlhý prvok poľa uloží 64 prvých hodnôt parametra enum, druhý prvok ďalších 64 atď.

EnumSet továrenské metódy vytvárajú inštancie jednej alebo druhej implementácie v závislosti od počtu prvkov súboru enum:

if (universe.length <= 64) return new RegularEnumSet (elementType, vesmír); else vráti nový JumboEnumSet (elementType, vesmír);

Majte na pamäti, že zohľadňuje iba veľkosť súboru enum triedy, nie počet prvkov, ktoré budú uložené v kolekcii.

3.2. Výhody plynúce z používania EnumSet

Z dôvodu implementácie EnumSet ktoré sme opísali vyššie, všetky metódy v EnumSet sú implementované pomocou aritmetických bitových operácií. Tieto výpočty sú veľmi rýchle, a preto sa všetky základné operácie vykonávajú v konštantnom čase.

Ak porovnáme EnumSet s iným Nastaviť implementácie ako HashSet, prvý je zvyčajne rýchlejší, pretože hodnoty sú uložené v predvídateľnom poradí a pre každý výpočet je potrebné preskúmať iba jeden bit. Na rozdiel od HashSet, nie je potrebné počítať hashcode nájsť správne vedro.

Navyše, vzhľadom na povahu bitových vektorov, an EnumSet je veľmi kompaktný a efektívny. Preto využíva menej pamäte so všetkými výhodami, ktoré prináša.

4. Hlavné operácie

Väčšina metód EnumSet pracovať ako každý iný Nastaviť, s výnimkou metód na vytváranie inštancií.

V ďalších častiach si podrobne ukážeme všetky tvorivé metódy a v skratke sa budeme venovať ostatným metódam.

V našich príkladoch budeme pracovať s a Farbaenum:

verejný výčet Farba {ČERVENÁ, ŽLTÁ, ZELENÁ, MODRÁ, ČIERNA, BIELA}

4.1. Tvorivé metódy

Najjednoduchšie metódy na vytvorenie súboru EnumSetvšetci z() a žiadny z(). Týmto spôsobom môžeme ľahko vytvoriť EnumSet obsahujúci všetky prvky našej Farba enum:

EnumSet.allOf (Color.class);

Rovnako môžeme použiť žiadny z() urobiť pravý opak a vytvoriť prázdnu zbierku súborov Farba:

EnumSet.noneOf (Color.class);

Ak chceme vytvoriť EnumSet s podskupinou enum prvky môžeme použiť preťažené z () metódy. Je dôležité rozlišovať medzi metódami s pevným počtom parametrov, ktoré môžu obsahovať až 5 rôznych, a metódami, ktoré používajú varargs:

Javadoc uvádza, že výkon varargs verzia môže byť kvôli vytvoreniu poľa pomalšia ako ostatné. Preto by sme ho mali používať, iba ak pôvodne potrebujeme pridať viac ako 5 prvkov.

Ďalším spôsobom, ako vytvoriť podmnožinu súboru enum je pomocou rozsah () metóda:

EnumSet.range (Color.ŽLUTÁ, Color.BLUE);

Vo vyššie uvedenom príklade je EnumSet obsahuje všetky prvky z žltá do Modrá. Dodržiavajú poradie definované v enum:

[ŽLTÁ, ZELENÁ, MODRÁ]

Všimnite si, že obsahuje prvý aj posledný zadaný prvok.

Ďalšou užitočnou továrenskou metódou je doplnok () čo nám umožňuje vylúčiť prvky odovzdané ako parametre. Vytvorme EnumSet so všetkým Farba prvky okrem čiernobielych:

EnumSet.complementOf (EnumSet.of (Color.BLACK, Color.WHITE));

Ak vytlačíme túto kolekciu, uvidíme, že obsahuje všetky ostatné prvky:

[ČERVENÁ, ŽLTÁ, ZELENÁ, MODRÁ]

Nakoniec môžeme vytvoriť EnumSet skopírovaním všetkých prvkov z iného EnumSet:

EnumSet.copyOf (EnumSet.of (Color.BLACK, Color.WHITE));

Vnútorne to nazýva klon metóda.

Navyše, môžeme tiež skopírovať všetky prvky z ľubovoľného Zbierka ktorý obsahuje enum prvkov. Použijeme ho na kopírovanie všetkých prvkov zoznamu:

List colorsList = new ArrayList (); colorsList.add (Color.RED); EnumSet listCopy = EnumSet.copyOf (colorsList);

V takom prípade listCopy obsahuje iba červenú farbu.

4.2. Ostatné operácie

Zvyšok operácií funguje úplne rovnako ako všetky ostatné Nastaviť implementácie a nie je rozdiel v ich použití.

Preto môžeme ľahko vytvoriť prázdny EnumSet a pridať nejaké prvky:

EnumSet set = EnumSet.noneOf (Color.class); set.add (Color.RED); set.add (Farebné ŽLTÉ)

Skontrolujte, či kolekcia obsahuje konkrétny prvok:

set.obsahuje (Color.RED);

Iterácia prvkov:

set.forEach (System.out :: println);

Alebo jednoducho odstráňte prvky:

sada.odstrániť (Color.RED);

To samozrejme medzi všetky ostatné operácie, ktoré a Nastaviť podporuje.

5. Záver

V tomto článku sme si ukázali hlavné vlastnosti EnumSet, jeho interná implementácia a ako môžeme mať z jeho používania úžitok.

Prebrali sme tiež hlavné metódy, ktoré ponúka, a implementovali sme niekoľko príkladov, ktoré nám ukazujú, ako ich môžeme použiť.

Celý zdrojový kód príkladov je ako vždy k dispozícii na serveri GitHub.


$config[zx-auto] not found$config[zx-overlay] not found