Gids voor EnumSet

1. Inleiding

In deze zelfstudie verkennen we de EnumSet collectie van de java.util pakket en bespreek zijn eigenaardigheden.

We zullen eerst de belangrijkste kenmerken van de collectie laten zien en daarna zullen we de binnenkant van de klas bekijken om de voordelen ervan te begrijpen.

Ten slotte bespreken we de belangrijkste bewerkingen die het biedt en implementeren we enkele basisvoorbeelden.

2. Wat is een EnumSet

Een EnumSet is een gespecialiseerd Set collectie om mee te werken opsomming klassen. Het implementeert het Set interface en strekt zich uit van AbstractSet:

Hoewel AbstractSet en AbstractCollection bieden implementaties voor bijna alle methoden van de Set en Verzameling interfaces, EnumSet overschrijft de meeste van hen.

Wanneer we van plan zijn om een EnumSet we moeten rekening houden met enkele belangrijke punten:

  • Het kan alleen opsomming waarden en alle waarden moeten bij hetzelfde horen opsomming
  • Het is niet toegestaan ​​om null-waarden toe te voegen, het gooien van een NullPointerException in een poging dit te doen
  • Het is niet draadveilig, dus we moeten het indien nodig extern synchroniseren
  • De elementen worden opgeslagen in de volgorde waarin ze zijn gedeclareerd in het opsomming
  • Het maakt gebruik van een fail-safe iterator dat werkt op een kopie, dus het zal geen ConcurrentModificationException als de verzameling wordt gewijzigd tijdens het herhalen ervan

3. Waarom gebruiken EnumSet

Als vuistregel, EnumSet moet altijd de voorkeur hebben boven alle andere Set implementatie wanneer we opslaan opsomming waarden.

In de volgende secties zullen we zien wat deze collectie beter maakt dan andere. Om dit te doen, zullen we kort de interne onderdelen van de klas laten zien om een ​​beter begrip te krijgen.

3.1. Implementatiedetails

EnumSet is een openbaarabstract klasse die meerdere statische fabrieksmethoden bevat waarmee we instanties kunnen maken. De JDK biedt 2 verschillende implementaties - zijn pakket-privé en ondersteund door een bitvector:

  • RegularEnumSet en
  • JumboEnumSet

RegularEnumSet gebruikt een enkele lang om de bitvector weer te geven. Elk stukje van de lang element vertegenwoordigt een waarde van de opsomming. De i-de waarde van de enum wordt opgeslagen in het i-de bit, dus het is vrij eenvoudig om te weten of een waarde aanwezig is of niet. Sinds lang is een 64-bits gegevenstype, deze implementatie kan maximaal 64 elementen opslaan.

Aan de andere kant, JumboEnumSet gebruikt een reeks lang elementen als een bitvector.Hierdoor kan deze implementatie meer dan 64 elementen opslaan. Het werkt ongeveer zoals het RegularEnumSet maar wat extra berekeningen maken om de array-index te vinden waarin de waarde is opgeslagen.

Het is niet verwonderlijk dat het eerste lange element van de array de 64 eerste waarden van de opsomming, het tweede element de volgende 64, enzovoort.

EnumSet factory-methoden creëren exemplaren van de ene implementatie of een andere, afhankelijk van het aantal elementen van het opsomming:

if (universe.length <= 64) retourneer nieuwe RegularEnumSet (elementType, universe); anders retourneert nieuwe JumboEnumSet (elementType, universe);

Houd er rekening mee dat er alleen rekening wordt gehouden met de grootte van de opsomming class, niet het aantal elementen dat in de collectie wordt opgeslagen.

3.2. Voordelen van het gebruik van een EnumSet

Vanwege de implementatie van een EnumSet die we hierboven hebben beschreven, alle methoden in een EnumSet worden geïmplementeerd met behulp van rekenkundige bitsgewijze bewerkingen. Deze berekeningen zijn erg snel en daarom worden alle basisbewerkingen in een constante tijd uitgevoerd.

Als we het vergelijken EnumSet met andere Set implementaties zoals HashSet, de eerste is meestal sneller omdat de waarden in een voorspelbare volgorde worden opgeslagen en er voor elke berekening slechts één bit hoeft te worden onderzocht. in tegenstelling tot HashSet, is het niet nodig om de hashcode om de juiste emmer te vinden.

Bovendien, vanwege de aard van bitvectoren, een EnumSet is erg compact en efficiënt. Daarom gebruikt het minder geheugen, met alle voordelen van dien.

4. Hoofdbewerkingen

De meeste methoden van een EnumSet werken als elk ander Set, met uitzondering van de methoden om instanties te maken.

In de volgende secties zullen we alle creatiemethoden in detail laten zien en zullen we de rest van de methoden kort behandelen.

In onze voorbeelden werken we met een Kleuropsomming:

openbare opsomming Kleur {ROOD, GEEL, GROEN, BLAUW, ZWART, WIT}

4.1. Creationele methoden

De meest eenvoudige methoden om een EnumSet zijn alles van() en geen van(). Op deze manier kunnen we eenvoudig een EnumSet met alle elementen van onze Kleur opsomming:

EnumSet.allOf (Color.class);

Evenzo kunnen we gebruiken geen van() om het tegenovergestelde te doen en een lege verzameling Kleur:

EnumSet.noneOf (Color.class);

Als we een EnumSet met een subset van de opsomming elementen kunnen we de overbelaste gebruiken van() methoden. Het is belangrijk om onderscheid te maken tussen de methoden met een vast aantal parameters tot 5 verschillende en degene die gebruikt varargs:

De Javadoc stelt dat de prestaties van de varargs versie kan langzamer zijn dan de andere vanwege het maken van de array. Daarom moeten we het alleen gebruiken als we in eerste instantie meer dan 5 elementen moeten toevoegen.

Een andere manier om een ​​subset van een opsomming is door de bereik () methode:

EnumSet.range (Color.YELLOW, Color.BLUE);

In het bovenstaande voorbeeld is de EnumSet bevat alle elementen van Geel naar Blauw. Ze volgen de volgorde die is gedefinieerd in het opsomming:

[GEEL, GROEN, BLAUW]

Merk op dat het zowel het eerste als het laatste gespecificeerde element bevat.

Een andere handige fabrieksmethode is de complementOf () waarmee we de elementen die als parameters zijn doorgegeven, kunnen uitsluiten. Laten we een EnumSet met alle Kleur elementen behalve zwart en wit:

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

Als we deze verzameling afdrukken, kunnen we zien dat deze alle andere elementen bevat:

[ROOD, GEEL, GROEN, BLAUW]

Tenslotte, we kunnen een EnumSet door alle elementen van een ander te kopiëren EnumSet:

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

Intern roept het de kloon methode.

Bovendien, we kunnen ook alle elementen van elk Verzameling dat bezit opsomming elementen. Laten we het gebruiken om alle elementen van een lijst te kopiëren:

Lijst colorsList = nieuwe ArrayList (); colorsList.add (Color.RED); EnumSet listCopy = EnumSet.copyOf (coloursList);

In dit geval is het listCopy bevat alleen de rode kleur.

4.2. Andere bewerkingen

De rest van de bewerkingen werkt op exact dezelfde manier als alle andere Set implementatie en er is geen verschil in het gebruik ervan.

Daarom kunnen we gemakkelijk een lege EnumSet en voeg enkele elementen toe:

EnumSet set = EnumSet.noneOf (Color.class); set.add (Color.RED); set.add (Color.YELLOW)

Controleer of de collectie een specifiek element bevat:

set.contains (Color.RED);

Herhaal de elementen:

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

Of verwijder eenvoudig elementen:

set.remove (Color.RED);

Dit, natuurlijk, naast alle andere bewerkingen die a Set ondersteunt.

5. Conclusie

In dit artikel hebben we de belangrijkste kenmerken van EnumSet, de interne implementatie ervan en hoe we hiervan kunnen profiteren.

We hebben ook de belangrijkste methoden besproken die het biedt en enkele voorbeelden geïmplementeerd om te laten zien hoe we ze kunnen gebruiken.

Zoals altijd is de volledige broncode van de voorbeelden beschikbaar op GitHub.


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