Un guide pour EnumMap

Un guide pour EnumMap

1. Vue d'ensemble

EnumMap est uneMap implementation qui prend exclusivementEnum comme clés.

Dans ce didacticiel, nous allons discuter de ses propriétés, des cas d'utilisation courants et du moment où nous devons l'utiliser.

2. Configuration du projet

Imaginez une simple exigence où nous devons cartographier les jours de la semaine avec le sport que nous pratiquons ce jour-là:

Monday     Soccer
Tuesday    Basketball
Wednesday  Hiking
Thursday   Karate

Pour cela, nous pourrions utiliser une énumération:

public enum DayOfWeek {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

Ce que nous verrons bientôt sera la clé de notre carte.

3. Création

Pour commencer à explorerEnumMap, nous devons d'abord en instancier un:

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");

Et voici notre première différence avec quelque chose de plus courant, commeHashMap. Notez qu'avecHashMap, le paramétrage du type est suffisant, ce qui signifie que nous pouvons nous en tirer avecnew HashMap<>(). However, EnumMap requires the key type in the constructor.

3.1. EnumMap Copy Constructeur

EnumMap est également livré avec deux constructeurs de copie. Le premier prend un autreEnumMap:

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");
activityMap.put(DayOfWeek.TUESDAY, "Basketball");

EnumMap activityMapCopy = new EnumMap<>(dayMap);
assertThat(activityMapCopy.size()).isEqualTo(2);
assertThat(activityMapCopy.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMapCopy.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");

3.2. Map Copy Constructeur

Ou,if we have a non-empty Map whose key is an enum, then we can do that, too:

Map ordinaryMap = new HashMap();
ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");

EnumMap enumMap = new EnumMap(ordinaryMap);
assertThat(enumMap.size()).isEqualTo(1);
assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

Notez que la mappe doit être non vide afin queEnumMap can détermine le type de clé à partir d'une entrée existante.

Si la carte spécifiée contient plus d'un type enum, le constructeur lanceraClassCastException.

4. Ajout et récupération d'éléments

Après avoir instancié unEnumMap, nous pouvons ajouter notre sport en utilisant la méthodeput():

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

Et pour le récupérer, nous pouvons utiliserget():

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

5. Vérification des éléments

Pour vérifier si nous avons un mappage défini pour un jour particulier, nous utilisonscontainsKey():

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

Et, pour vérifier si un sport particulier est mappé sur une clé, nous utilisonscontainsValue():

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

5.1. null comme valeur

Maintenant,null est une valeur sémantiquement valide pourEnumMap.

Associonsnull à "ne rien faire" et mappons-le à samedi:

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. Supprimer des éléments

Afin de démapper un jour particulier, nous leremove() simplement:

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

Comme nous pouvons l'observer,remove(key) renvoie la valeur précédente associée à la clé, ounull  s'il n'y avait pas de mappage pour la clé.

On peut aussi choisir deunmap a particular day only if that day is mapped to a particular activity:

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

remove(key, value) supprime l'entrée pour la clé spécifiée uniquement si la clé est actuellement mappée à la valeur spécifiée.

7. Vues de la collection

Tout comme avec les cartes ordinaires, avec n'importe quelEnumMap, nous pouvons avoir 3 vues ou sous-collections différentes.

Commençons par créer une nouvelle carte de nos activités:

EnumMap activityMap = new EnumMap(DayOfWeek.class);
activityMap.put(DayOfWeek.THURSDAY, "Karate");
activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
activityMap.put(DayOfWeek.MONDAY, "Soccer");

7.1. values

La première vue de notre carte d'activité estvalues() qui, comme son nom l'indique, renvoie toutes les valeurs de la carte:

Collection values = dayMap.values();
assertThat(values)
  .containsExactly("Soccer", "Hiking", "Karate");

Notez ici queEnumMap  est une carte ordonnée. Il utilise l'ordre du sénumDayOfWeek pour déterminer l'ordre des entrées.

7.2. keySet

De même,keySet() renvoie une collection de clés, toujours dans l'ordre d'énumération:

Set keys = dayMap.keySet();
assertThat(keys)
        .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY);

7.3. entrySet

Enfin,entrySet() renvoie le mappage par paires de clé et de valeur:

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

La commande dans une carte peut certainement être utile, et nous allons plus en profondeur dans notre tutoriel quecompares TreeMap to HashMap.

7.4. Mutabilité

Maintenant, rappelez-vous que toutes les modifications que nous apportons à la carte d'activité d'origine seront reflétées dans l'une de ses vues:

activityMap.put(DayOfWeek.TUESDAY, "Basketball");
assertThat(values)
    .containsExactly("Soccer", "Basketball", "Hiking", "Karate");

Et vice versa; toute modification apportée aux sous-vues sera reflétée dans la carte d'activité d'origine:

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

Par contrat deEnumMap avec l'interfaceMap , les sous-vues sont soutenues par la carte d'origine.

8. Quand utiliserEnumMap

8.1. Performance

L'utilisation deEnum comme clé permet de faire une optimisation supplémentaire des performances,like a quicker hash computation since all possible keys are known in advance.

La simplicité d'avoirenum comme clé signifie queEnumMap ne doit être sauvegardé que par un ancien JavaArray avec une logique très simple pour le stockage et la récupération. D'un autre côté, lesMap implementations génériques doivent répondre aux préoccupations liées au fait d'avoir un objet générique comme clé. Par exemple,HashMap https: //www.example.com/java-hashmap [nécessite une structure de données complexe et une logique de stockage et de récupération considérablement plus complexe] pour tenir compte de la possibilité d'une collision de hachage.

8.2. La fonctionnalité

De plus, comme nous l'avons vu,EnumMap  est une carte ordonnée, en ce sens que ses vues seront itérées dans l'ordre d'énumération. Pour obtenir un comportement similaire pour des scénarios plus complexes, nous pouvons regarderTreeMap ouLinkedHashMap.

9. Conclusion

Dans cet article, nous avons exploré l'implémentationEnumMap de l'interfaceMap. Lorsque vous travaillez avecEnum  comme clé, l'analyseEnumMap est utile.

Le code source complet de tous les exemples utilisés dans ce didacticiel se trouve dans lesGitHub project.