Guide til EnumSet

1. Introduksjon

I denne opplæringen vil vi utforske EnumSet samling fra java.util pakke og diskutere dens særegenheter.

Vi viser først hovedtrekkene i samlingen, og etter det går vi gjennom klassene for å forstå fordelene.

Til slutt vil vi dekke hovedoperasjonene som det gir, og implementere noen grunnleggende eksempler.

2. Hva er en EnumSet

An EnumSet er spesialist Sett samling å jobbe med enum klasser. Den implementerer Sett grensesnitt og strekker seg fra Abstrakt sett:

Selv om Abstrakt sett og Abstrakt Samling gi implementeringer for nesten alle metodene i Sett og Samling grensesnitt, EnumSet overstyrer de fleste av dem.

Når vi planlegger å bruke en EnumSet vi må ta noen viktige punkter i betraktning:

  • Den kan bare inneholde enum verdier og alle verdiene må tilhøre det samme enum
  • Det tillater ikke å legge til nullverdier, kaster en NullPointerException i et forsøk på å gjøre det
  • Det er ikke trådsikkert, så vi må synkronisere den eksternt om nødvendig
  • Elementene lagres i den rekkefølgen de er deklarert i enum
  • Den bruker en feilsikker iterator som fungerer på en kopi, så det vil ikke kaste et ConcurrentModificationException hvis samlingen endres når den gjentas over den

3. Hvorfor bruke EnumSet

Som en tommelregel, EnumSet bør alltid foretrekkes fremfor andre Sett implementering når vi lagrer enum verdier.

I de neste avsnittene vil vi se hva som gjør denne samlingen bedre enn andre. For å gjøre det, vil vi kort vise internt i klassen for å få en bedre forståelse.

3.1. Implementeringsdetaljer

EnumSet er en offentligabstrakt klasse som inneholder flere statiske fabrikkmetoder som lar oss lage forekomster. JDK tilbyr to forskjellige implementeringer - er pakke-privat og støttet av litt vektor:

  • RegularEnumSet og
  • JumboEnumSet

RegularEnumSet bruker en singel lang å representere bitvektoren. Hver bit av lang element representerer en verdi av enum. I-th-verdien til enum vil bli lagret i i-bit, så det er ganske enkelt å vite om en verdi er tilstede eller ikke. Siden lang er en 64-bit datatype, kan denne implementeringen lagre opptil 64 elementer.

På den andre siden, JumboEnumSet bruker en rekke lang elementer som litt vektor.Dette lar denne implementeringen lagre mer enn 64 elementer. Det fungerer omtrent som RegularEnumSet men gjør noen ekstra beregninger for å finne matriceindeksen der verdien er lagret.

Ikke overraskende vil det første lange elementet i matrisen lagre de 64 første verdiene til enum, det andre elementet neste 64, og så videre.

EnumSet fabrikkmetoder oppretter forekomster av en eller annen implementering avhengig av antall elementer i enum:

hvis (universe.length <= 64) returnerer nytt RegularEnumSet (elementType, universe); ellers returnerer nye JumboEnumSet (elementType, univers);

Husk at det bare tar hensyn til størrelsen på enum klasse, ikke antall elementer som vil bli lagret i samlingen.

3.2. Fordeler med å bruke en EnumSet

På grunn av implementeringen av en EnumSet som vi har beskrevet ovenfor, alle metodene i en EnumSet er implementert ved hjelp av aritmetiske bitvise operasjoner. Disse beregningene er veldig raske, og derfor utføres alle grunnleggende operasjoner på konstant tid.

Hvis vi sammenligner EnumSet med andre Sett implementeringer som HashSet, den første er vanligvis raskere fordi verdiene er lagret i en forutsigbar rekkefølge og bare en bit må undersøkes for hver beregning. I motsetning til HashSet, det er ikke nødvendig å beregne hashcode for å finne riktig bøtte.

Videre, på grunn av beskaffenheten til bitvektorer, an EnumSet er veldig kompakt og effektiv. Derfor bruker den mindre minne, med alle fordelene det gir.

4. Hovedoperasjoner

Flertallet av metodene til en EnumSet fungerer som alle andre Sett, med unntak av metodene for å opprette forekomster.

I de neste avsnittene vil vi vise i detalj alle skapelsesmetodene, og vi vil kort dekke resten av metodene.

I eksemplene våre jobber vi med en Fargeenum:

offentlig enum Farge {RØD, GUL, GRØNN, BLÅ, SVART, HVIT}

4.1. Skapelsesmetoder

De mest enkle metodene for å lage en EnumSet er alt() og ingen av(). På denne måten kan vi enkelt lage en EnumSet inneholder alle elementene i vår Farge enum:

EnumSet.allOf (Color.class);

På samme måte kan vi bruke ingen av() å gjøre det motsatte og lage en tom samling av Farge:

EnumSet.noneOf (Color.class);

Hvis vi ønsker å lage en EnumSet med en delmengde av enum elementer vi kan bruke overbelastet av() metoder. Det er viktig å skille mellom metodene med et fast antall parametere opptil 5 forskjellige og den som bruker varargs:

Javadoc uttaler at ytelsen til varargs versjonen kan være tregere enn de andre på grunn av opprettelsen av matrisen. Derfor bør vi bare bruke den hvis vi i utgangspunktet trenger å legge til mer enn 5 elementer.

En annen måte å lage et delsett av en enum er ved å bruke område() metode:

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

I eksemplet ovenfor er EnumSet inneholder alle elementene fra Gul til Blå. De følger rekkefølgen definert i enum:

[GUL, GRØNN, BLÅ]

Legg merke til at den inkluderer både det første og det siste elementet som er spesifisert.

En annen nyttig fabrikkmetode er complementOf () som lar oss ekskludere elementene som sendes som parametere. La oss lage en EnumSet med alle Farge elementer unntatt svart og hvitt:

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

Hvis vi skriver ut denne samlingen, kan vi se at den inneholder alle de andre elementene:

[RØD, GUL, GRØNN, BLÅ]

Endelig, vi kan lage en EnumSet ved å kopiere alle elementene fra en annen EnumSet:

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

Internt kaller det klone metode.

Videre vi kan også kopiere alle elementene fra hvilken som helst Samling som inneholder enum elementer. La oss bruke den til å kopiere alle elementene i en liste:

Liste fargerListe = ny ArrayList (); colorsList.add (Color.RED); EnumSet listCopy = EnumSet.copyOf (colourList);

I dette tilfellet listCopy inneholder bare den røde fargen.

4.2. Andre operasjoner

Resten av operasjonene fungerer på nøyaktig samme måte som andre Sett implementering, og det er ingen forskjell i hvordan du bruker dem.

Derfor kan vi enkelt lage en tom EnumSet og legg til noen elementer:

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

Sjekk om samlingen inneholder et bestemt element:

set.contains (Color.RED);

Iterer over elementene:

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

Eller bare fjern elementer:

set.remove (Color.RED);

Dette, selvfølgelig, blant alle de andre operasjonene som a Sett støtter.

5. Konklusjon

I denne artikkelen har vi vist hovedtrekkene til EnumSet, dens interne implementering og hvordan vi kan ha nytte av å bruke den.

Vi har også dekket hovedmetodene den tilbyr og implementert noen eksempler for å vise hvordan vi kan bruke dem.

Som alltid er hele kildekoden til eksemplene tilgjengelig på GitHub.


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