Implémentations de cartes immuables en Java

1. Vue d'ensemble

Il est parfois préférable d'interdire les modifications de java.util.Map telles que le partage de données en lecture seule entre les threads. Pour cela, nous pouvons utiliser soit une carte non modifiable, soit une carte immuable.

Dans ce rapide tutoriel, nous verrons quelle est la différence entre eux. Ensuite, nous présenterons différentes manières de créer une carte immuable.

2. Non modifiable vs immuable

Une carte non modifiable est juste un wrapper sur une carte modifiable et elle ne permet pas de modifications directement:

Map mutableMap = new HashMap(); mutableMap.put("USA", "North America"); Map unmodifiableMap = Collections.unmodifiableMap(mutableMap); assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("Canada", "North America"));

Mais la carte mutable sous-jacente peut toujours être modifiée et les modifications sont également reflétées dans la carte non modifiable:

mutableMap.remove("USA"); assertFalse(unmodifiableMap.containsKey("USA")); mutableMap.put("Mexico", "North America"); assertTrue(unmodifiableMap.containsKey("Mexico"));

Une carte immuable, en revanche, contient ses propres données privées et ne permet pas de modifications. Par conséquent, les données ne peuvent en aucun cas changer une fois qu'une instance de la carte immuable est créée.

3. Carte immuable de Guava

Guava fournit des versions immuables de chaque java.util . Carteen utilisant ImmutableMap . Il lève une UnsupportedOperationException chaque fois que nous essayons de le modifier.

Puisqu'il contient ses propres données privées, ces données ne changeront pas lorsque la carte d'origine est modifiée.

Nous allons maintenant discuter de différentes façons de créer des instances d' ImmutableMap.

3.1. Utilisation copyOf () Méthode

Tout d'abord, utilisons la méthode ImmutableMap.copyOf () qui renvoie une copie de toutes les entrées comme dans la carte d'origine:

ImmutableMap immutableMap = ImmutableMap.copyOf(mutableMap); assertTrue(immutableMap.containsKey("USA"));

Il ne peut pas être modifié directement ou indirectement:

assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); mutableMap.remove("USA"); assertTrue(immutableMap.containsKey("USA")); mutableMap.put("Mexico", "North America"); assertFalse(immutableMap.containsKey("Mexico"));

3.2. Utilisation de la méthode builder ()

Nous pouvons également utiliser la méthode ImmutableMap.builder () pour créer une copie de toutes les entrées comme dans la carte d'origine.

De plus, nous pouvons utiliser cette méthode pour ajouter des entrées supplémentaires qui ne sont pas présentes dans la carte d'origine:

ImmutableMap immutableMap = ImmutableMap.builder() .putAll(mutableMap) .put("Costa Rica", "North America") .build(); assertTrue(immutableMap.containsKey("USA")); assertTrue(immutableMap.containsKey("Costa Rica"));

De la même manière que dans l'exemple précédent, nous ne pouvons pas le modifier directement ou indirectement:

assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); mutableMap.remove("USA"); assertTrue(immutableMap.containsKey("USA")); mutableMap.put("Mexico", "North America"); assertFalse(immutableMap.containsKey("Mexico"));

3.3. Utilisation de la méthode ()

Enfin, nous pouvons utiliser la méthode ImmutableMap.of () pour créer une carte immuable avec un ensemble d'entrées fournies à la volée. Il prend en charge au plus cinq paires clé / valeur:

ImmutableMap immutableMap = ImmutableMap.of("USA", "North America", "Costa Rica", "North America"); assertTrue(immutableMap.containsKey("USA")); assertTrue(immutableMap.containsKey("Costa Rica"));

Nous ne pouvons pas non plus le modifier:

assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America"));

4. Conclusion

Dans cet article rapide, nous avons discuté des différences entre une carte non modifiable et une carte immuable.

Nous avons également examiné différentes façons de créer ImmutableMap de Guava .

Et, comme toujours, les exemples de code complets sont disponibles à l'adresse over sur GitHub.