Een gids voor EnumMap

1. Overzicht

EnumMap is een Kaart implementatie die uitsluitend duurt Enum als zijn sleutels.

In deze zelfstudie bespreken we de eigenschappen, algemene gebruiksscenario's en wanneer we deze zouden moeten gebruiken.

2. Projectconfiguratie

Stel je een eenvoudige vereiste voor waarbij we de dagen van de week in kaart moeten brengen met de sport die we die dag spelen:

Maandag Voetbal Dinsdag Basketbal Woensdag Wandeling Donderdag Karate 

Hiervoor kunnen we een enum gebruiken:

openbare lijst DayOfWeek {MAANDAG, DINSDAG, WOENSDAG, DONDERDAG, VRIJDAG, ZATERDAG, ZONDAG}

Wat we binnenkort zullen zien, zal de sleutel zijn voor onze kaart.

3. Creatie

Om te beginnen met verkennen EnumMap, eerst moeten we er een instantiëren:

EnumMap activityMap = nieuwe EnumMap (DayOfWeek.class); activityMap.put (DayOfWeek.MONDAY, "Voetbal"); 

En hier is ons eerste verschil met iets dat vaker voorkomt, zoals Hash kaart. Merk op dat met Hash kaart, is de parametrisering van het type voldoende, wat betekent dat we ermee weg kunnen komen nieuwe HashMap (). Echter, EnumMap vereist het sleuteltype in de constructor.

3.1. EnumMap Kopieer Constructor

EnumMap wordt ook geleverd met twee kopie-constructeurs. De eerste neemt een andere EnumMap:

EnumMap activityMap = nieuwe EnumMap (DayOfWeek.class); activityMap.put (DayOfWeek.MONDAY, "Voetbal"); activityMap.put (DayOfWeek.TUESDAY, "Basketball"); EnumMap activityMapCopy = nieuwe EnumMap (dayMap); assertThat (activityMapCopy.size ()). isEqualTo (2); assertThat (activityMapCopy.get (DayOfWeek.MONDAY)). isEqualTo ("Voetbal"); assertThat (activityMapCopy.get (DayOfWeek.TUESDAY)). isEqualTo ("Basketball");

3.2. Kaart Kopieer Constructor

Of, als we een niet-leeg hebben Kaart wiens sleutel een opsomming is, dan kunnen we dat ook doen:

Map gewoneMap = nieuwe HashMap (); gewoneMap.put (DayOfWeek.MONDAY, "Voetbal"); EnumMap enumMap = nieuwe EnumMap (gewoneMap); assertThat (enumMap.size ()). isEqualTo (1); assertThat (enumMap.get (DayOfWeek.MONDAY)). isEqualTo ("Soccer");

Merk op dat de kaart niet leeg mag zijn, zodat EnumMap kan het sleuteltype bepalen uit een bestaand item.

Als de opgegeven kaart meer dan één enum-type bevat, zal de constructor gooien ClassCastException.

4. Elementen toevoegen en ophalen

Na het instantiëren van een EnumMap, kunnen we onze sport toevoegen met de leggen() methode:

activityMap.put (DayOfWeek.MONDAY, "Voetbal");

En om het op te halen, kunnen we gebruiken krijgen():

assertThat (clubMap.get (DayOfWeek.MONDAY)). isEqualTo ("Voetbal");

5. Controleren op elementen

Om te controleren of we een mapping hebben gedefinieerd voor een bepaalde dag, gebruiken we bevatKey ():

activityMap.put (DayOfWeek.WEDNESDAY, "Wandelen"); assertThat (activityMap.containsKey (DayOfWeek.WEDNESDAY)). isTrue ();

En om te controleren of een bepaalde sport is toegewezen aan een sleutel die we gebruiken bevatValue ():

assertThat (activityMap.containsValue ("Wandelen")). isTrue (); 

5.1. nul als waarde

Nu, nul is een semantisch geldige waarde voor EnumMap.

Laten we associëren nul met "niets doen", en dit toewijzen aan zaterdag:

assertThat (activityMap.containsKey (DayOfWeek.SATURDAY)). isFalse (); assertThat (activityMap.containsValue (null)). isFalse (); activityMap.put (DayOfWeek.SATURDAY, null); assertThat (activityMap.containsKey (DayOfWeek.SATURDAY)). isTrue (); assertThat (activityMap.containsValue (null)). isTrue ();

6. Elementen verwijderen

Om een ​​bepaalde dag te ontkoppelen, doen we gewoon verwijderen() het:

activityMap.put (DayOfWeek.MONDAY, "Voetbal"); assertThat (activityMap.remove (DayOfWeek.MONDAY)). isEqualTo ("Voetbal"); assertThat (activityMap.containsKey (DayOfWeek.MONDAY)). isFalse (); 

Zoals we kunnen zien, verwijderen (sleutel) geeft de vorige waarde terug die aan de sleutel is gekoppeld, of nul als er geen toewijzing was voor de sleutel.

We kunnen er ook voor kiezen een bepaalde dag uit de kaart halen alleen als die dag is toegewezen aan een bepaalde activiteit:

activityMap.put (DayOfWeek.Monday, "Soccer"); assertThat (activityMap.remove (DayOfWeek.Monday, "Hiking")). isEqualTo (false); assertThat (activityMap.remove (DayOfWeek.Monday, "Soccer")). isEqualTo (true); 

verwijderen (sleutel, waarde) verwijdert de vermelding voor de opgegeven sleutel alleen als de sleutel momenteel is toegewezen aan de opgegeven waarde.

7. Collectieweergaven

Net als bij gewone kaarten, met alle EnumMapkunnen we 3 verschillende weergaven of subcollecties hebben.

Laten we eerst een nieuwe kaart maken van onze activiteiten:

EnumMap activityMap = nieuwe EnumMap (DayOfWeek.class); activityMap.put (DayOfWeek.THURSDAY, "Karate"); activityMap.put (DayOfWeek.WEDNESDAY, "Wandelen"); activityMap.put (DayOfWeek.MONDAY, "Voetbal");

7.1. waarden

De eerste weergave van onze activiteitenkaart is waarden () die, zoals de naam suggereert, alle waarden op de kaart retourneert:

Verzamelingswaarden = dayMap.values ​​(); assertThat (waarden) .containsExactly ("Voetbal", "Wandelen", "Karate"); 

Merk hier op dat EnumMap is een geordende kaart. Het gebruikt de volgorde van de Dag van de week enum om de volgorde van de vermeldingen te bepalen.

7.2. sleutelbos

Evenzo sleutelbos() geeft een verzameling sleutels terug, opnieuw in opsommingsvolgorde:

Stel sleutels in = dayMap.keySet (); assertThat (toetsen) .containsExactly (DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY); 

7.3. entrySet

Ten slotte, entrySet () geeft de afbeelding terug in paren van sleutel en waarde:

assertThat (dayMap.entrySet ()) .containsExactly (nieuwe SimpleEntry (DayOfWeek.MONDAY, "Soccer"), nieuwe SimpleEntry (DayOfWeek.WEDNESDAY, "Hiking"), nieuwe SimpleEntry (DayOfWeek.THURSDAY, "Karate")); 

Bestellen in een kaart kan zeker van pas komen, en we gaan dieper in op onze tutorial die TreeMap vergelijkt met HashMap.

7.4. Veranderlijkheid

Onthoud nu dat alle wijzigingen die we aanbrengen in de oorspronkelijke activiteitenkaart, worden weerspiegeld in alle weergaven:

activityMap.put (DayOfWeek.TUESDAY, "Basketball"); assertThat (waarden) .containsExactly ("Voetbal", "Basketbal", "Wandelen", "Karate"); 

En vice versa; alle wijzigingen die we aanbrengen in de subweergaven worden weerspiegeld in de originele activiteitenkaart:

values.remove ("Wandelen"); assertThat (activityMap.containsKey (DayOfWeek.WEDNESDAY)). isFalse (); assertThat (activityMap.size ()). isEqualTo (3); 

Per EnumMapHeeft een contract met Kaart interface, worden de subweergaven ondersteund door de originele kaart.

8. Wanneer te gebruiken EnumMap

8.1. Prestatie

Gebruik makend van Enum omdat de sleutel het mogelijk maakt om wat extra prestatie-optimalisatie door te voeren, als een snellere hash-berekening, aangezien alle mogelijke sleutels van tevoren bekend zijn.

De eenvoud van het hebben opsomming als belangrijkste middel EnumMap hoeft alleen te worden ondersteund door een gewone oude Java Array met zeer eenvoudige logica voor opslag en ophalen. Aan de andere kant, generiek Kaart implementaties moeten rekening houden met zorgen met betrekking tot het hebben van een generiek object als de sleutel. Bijvoorbeeld, Hash kaart heeft een complexe datastructuur en een aanzienlijk complexere logica voor opslaan en ophalen nodig om rekening te houden met de mogelijkheid van hash-botsingen.

8.2. Functionaliteit

Zoals we zagen, EnumMap is een geordende kaart, in die zin dat de weergaven in opsommingsvolgorde worden herhaald. Om vergelijkbaar gedrag te krijgen voor complexere scenario's, kunnen we kijken naar TreeMap of LinkedHashMap.

9. Conclusie

In dit artikel hebben we de EnumMap implementatie van de Kaart koppel. Bij het werken met Enum als sleutel, EnumMap kan van pas komen.

De volledige broncode voor alle voorbeelden die in deze tutorial worden gebruikt, is te vinden in het GitHub-project.