Útmutató az EnumSet-hez

1. Bemutatkozás

Ebben az oktatóanyagban a EnumSet gyűjtemény a java.util csomagot, és megvitassák annak sajátosságait.

Először bemutatjuk a kollekció főbb jellemzőit, majd ezek után áttekintjük az osztály belsejét, hogy megértsük annak előnyeit.

Végül kitérünk az általa nyújtott főbb műveletekre, és néhány alapvető példát megvalósítunk.

2. Mi az a EnumSet

An EnumSet szakosodott Készlet kollekció dolgozni enum osztályok. Megvalósítja a Készlet felületen, és onnan terjed ki AbstractSet:

Annak ellenére AbstractSet és AbstractCollection a megvalósítás biztosítása a Készlet és Gyűjtemény interfészek, EnumSet felülírja a legtöbbjüket.

Amikor azt tervezzük, hogy egy EnumSet néhány fontos szempontot figyelembe kell vennünk:

  • Csak tartalmazhat enum értékek és az összes értéknek azonosnak kell lennie enum
  • Nem engedélyezi nullértékek hozzáadását, dobott egy NullPointerException annak megkísérlésére
  • Ez nem szálkás, ezért szükség esetén külsőleg kell szinkronizálnunk
  • Az elemeket a sorrendben tároljuk, amelyben deklaráltuk az enum
  • Meghibásodásmentes iterátort használ ami működik egy példányon, így nem dobja el a ConcurrentModificationException ha a gyűjtemény módosul, amikor iterálnak rajta

3. Miért kell használni EnumSet

Mint egy ökölszabály, EnumSet mindig előnyben kell részesíteni másokkal szemben Készlet megvalósítás, amikor tárolunk enum értékek.

A következő szakaszokban meglátjuk, mitől jobb ez a gyűjtemény, mint mások. Ennek érdekében röviden megmutatjuk az osztály belsejét, hogy jobban megértsük.

3.1. A megvalósítás részletei

EnumSet egy nyilvánosabsztrakt osztály, amely több statikus gyári metódust tartalmaz, amelyek lehetővé teszik számunkra példányok létrehozását. A JDK 2 különböző megvalósítást biztosít - vannak csomag-privát és egy bit vektorral alátámasztva:

  • RegularEnumSet és
  • JumboEnumSet

RegularEnumSet kislemezt használ hosszú hogy a bit vektort ábrázolja. Minden egyes hosszú elem a enum. Az enum i-edik értéke az i-edik bitben lesz tárolva, így nagyon könnyű megtudni, hogy van-e érték vagy sem. Mivel hosszú egy 64 bites adattípus, ez a megvalósítás legfeljebb 64 elemet képes tárolni.

Másrészről, JumboEnumSet tömböt használ hosszú elemek, mint egy bit vektor.Ez lehetővé teszi, hogy ez a megvalósítás több mint 64 elemet tároljon. Nagyjából úgy működik, mint a RegularEnumSet de néhány extra számítást végez a tömbindex megtalálásához, ahol az érték tárolva van.

Nem meglepő, hogy a tömb első hosszú eleme a 64 első értékét tárolja enum, a második elem a következő 64, és így tovább.

EnumSet A gyári módszerek az egyik vagy másik megvalósítás példányait hozzák létre, a enum:

if (univerzum.hossz <= 64) visszatér új RegularEnumSet (elementType, univerzum); különben adja vissza az új JumboEnumSet-t (elementType, univerzum);

Ne feledje, hogy csak a enum osztály, nem pedig a gyűjteményben tárolandó elemek száma.

3.2. Előnyök az EnumSet

An megvalósítása miatt EnumSet amit fent leírtunk, az EnumSet összes metódusát aritmetikai bitenkénti műveletek segítségével hajtják végre. Ezek a számítások nagyon gyorsak, ezért az összes alapvető műveletet állandó idő alatt hajtják végre.

Ha összehasonlítjuk EnumSet mással Készlet megvalósítások, mint HashSet, az első általában gyorsabb, mert az értékeket kiszámítható sorrendben tárolják, és minden kiszámításhoz csak egy bitet kell megvizsgálni. nem úgy mint HashSet, nincs szükség a hash kód hogy megtalálja a megfelelő vödröt.

Sőt, a bit vektorok jellege miatt egy EnumSet nagyon kompakt és hatékony. Ezért kevesebb memóriát használ, minden előnyével együtt.

4. Fő műveletek

A módszerek többsége EnumSet működik, mint bármely más Készlet, kivéve a példányok létrehozásának módszereit.

A következő szakaszokban részletesen bemutatjuk az összes alkotási módszert, és röviden kitérünk a többi módszerre.

Példáinkban a Színenum:

nyilvános enum szín: {VÖRÖS, SÁRGA, ZÖLD, KÉK, FEKETE, FEHÉR}

4.1. Teremtési módszerek

A legegyszerűbb módszerek az EnumSet vannak az összes() és egyik sem(). Így könnyen létrehozhatunk egy EnumSet amely minden elemünket tartalmazza Szín enum:

EnumSet.allOf (Color.class);

Hasonlóképpen használhatjuk egyik sem() hogy ennek az ellenkezőjét tegyük és üres gyűjteményt hozzunk létre Szín:

EnumSet.noneOf (Color.class);

Ha létre akarunk hozni egy EnumSet részhalmazával enum elemeket használhatjuk a túlterheltek nak,-nek() mód. Fontos megkülönböztetni a rögzített számú, legfeljebb 5 különböző paramétert és a használt módszert varargs:

A javadoc kijelenti, hogy a varargs verzió a tömb létrehozása miatt lassabb lehet, mint a többi. Ezért csak akkor használjuk, ha kezdetben több mint 5 elemet kell hozzáadnunk.

Az an részhalmazának létrehozásának másik módja enum a hatótávolság() módszer:

EnumSet.range (szín.SÁRGA, szín.KÉK);

A fenti példában a EnumSet a (z) összes elemét tartalmazza Sárga nak nek Kék. A programban meghatározott sorrendet követik enum:

[SÁRGA, ZÖLD, KÉK]

Vegye figyelembe, hogy az első és az utolsó elemeket egyaránt tartalmazza.

Egy másik hasznos gyári módszer a plementOf () amely lehetővé teszi számunkra a paraméterként átadott elemek kizárását. Hozzunk létre egy EnumSet az összes Szín elemek, a fekete-fehér kivételével:

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

Ha kinyomtatjuk ezt a gyűjteményt, láthatjuk, hogy az összes többi elemet tartalmazza:

[VÖRÖS, SÁRGA, ZÖLD, KÉK]

Végül, létrehozhatunk egy EnumSet az összes elem másolásával egy másikból EnumSet:

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

Belsőleg hívja a klón módszer.

Ráadásul, az összes elemet bármelyikről másolhatjuk is Gyűjtemény hogy tartalmazza enum elemek. Használjuk a lista összes elemének másolásához:

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

Ebben az esetben a listCopy csak a piros színt tartalmazza.

4.2. Egyéb műveletek

A többi művelet pontosan ugyanúgy működik, mint bármely más Készlet megvalósítás és nincs különbség a felhasználásuk módjában.

Ezért könnyen létrehozhatunk egy üreset EnumSet és adjon hozzá néhány elemet:

EnumSet set = EnumSet.noneOf (Szín.osztály); set.add (Color.RED); set.add (Szín.SÁRGA)

Ellenőrizze, hogy a gyűjtemény tartalmaz-e egy meghatározott elemet:

készlet.tart (Color.RED);

Az elemek elemzése:

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

Vagy egyszerűen távolítsa el az elemeket:

set.remove (Color.RED);

Ez természetesen az összes többi művelet mellett, amelyek a Készlet támogatja.

5. Következtetés

Ebben a cikkben bemutattuk a EnumSet, annak belső megvalósítását, és hogyan profitálhatunk a használatából.

Áttekintettük az általa kínált főbb módszereket, és néhány példát bemutattunk annak bemutatására, hogyan tudjuk ezeket használni.

Mint mindig, a példák teljes forráskódja elérhető a GitHubon.


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