Guide d'Apache Commons MultiValuedMap

1. Vue d'ensemble

Dans ce rapide tutoriel, nous allons jeter un œil à l' interface MultiValuedMap fournie dans la bibliothèque Apache Commons Collections .

MultiValuedMap fournit une API simple pour mapper chaque clé à une collection de valeurs en Java. C'est le successeur de org.apache.commons.collections4.MultiMap, qui était obsolète dans Commons Collection 4.1.

2. Dépendance de Maven

Pour les projets Maven, nous devons ajouter la dépendance commons-collections4 :

 org.apache.commons commons-collections4 4.2 

3. Ajout d'éléments dans une MultiValuedMap

Nous pouvons ajouter des éléments en utilisant les méthodes put et putAll .

Commençons par créer une instance de MultiValuedMap :

MultiValuedMap map = new ArrayListValuedHashMap();

Ensuite, voyons comment nous pouvons ajouter des éléments un à la fois en utilisant la méthode put :

map.put("fruits", "apple"); map.put("fruits", "orange");

De plus, ajoutons quelques éléments à l'aide de la méthode putAll , qui mappe une clé à plusieurs éléments en un seul appel:

map.putAll("vehicles", Arrays.asList("car", "bike")); assertThat((Collection) map.get("vehicles")) .containsExactly("car", "bike");

4. Récupération des éléments d'une MultiValuedMap

MultiValuedMap fournit des méthodes pour récupérer des clés, des valeurs et des mappages clé-valeur. Jetons un coup d'œil à chacun de ceux-ci.

4.1. Obtenir toutes les valeurs d'une clé

Pour obtenir toutes les valeurs associées à une clé, nous pouvons utiliser la méthode get , qui renvoie une Collection :

assertThat((Collection) map.get("fruits")) .containsExactly("apple", "orange");

4.2. Obtenir tous les mappages clé-valeur

Ou, nous pouvons utiliser la méthode des entrées pour obtenir une collection de tous les mappages clé-valeur contenus dans la carte:

Collection
    
      entries = map.entries();
    

4.3. Obtenir toutes les clés

Il existe deux méthodes pour récupérer toutes les clés contenues dans un MultiValuedMap.

Utilisons la méthode keys pour obtenir une vue MultiSet des clés:

MultiSet keys = map.keys(); assertThat(keys).contains("fruits", "vehicles");

Sinon, nous pouvons obtenir un ensemble vue des clés à l' aide du keySet méthode:

Set keys = map.keySet(); assertThat(keys).contains("fruits", "vehicles");

4.4. Obtenir toutes les valeurs d'une carte

Enfin, si nous voulons obtenir une vue Collection de toutes les valeurs contenues dans la carte, nous pouvons utiliser la méthode values :

Collection values = map.values(); assertThat(values).contains("apple", "orange", "car", "bike");

5. Suppression d'éléments d'une MultiValuedMap

Examinons maintenant toutes les méthodes de suppression d'éléments et de mappages clé-valeur.

5.1. Supprimer tous les éléments mappés à une clé

Voyons d'abord comment supprimer toutes les valeurs associées à une clé spécifiée à l'aide de la méthode remove :

Collection removedValues = map.remove("fruits"); assertThat(map.containsKey("fruits")).isFalse(); assertThat(removedValues).contains("apple", "orange");

Cette méthode retourne une vue Collection des valeurs supprimées.

5.2. Supprimer un mappage clé-valeur unique

Maintenant, supposons que nous ayons une clé mappée à plusieurs valeurs, mais que nous souhaitons supprimer une seule des valeurs mappées, en laissant les autres. Nous pouvons facilement le faire en utilisant la méthode removeMapping :

boolean isRemoved = map.removeMapping("fruits","apple"); assertThat(map.containsMapping("fruits","apple")).isFalse();

5.3. Supprimer tous les mappages clé-valeur

Et enfin, nous pouvons utiliser la méthode clear pour supprimer tous les mappages de la carte:

map.clear(); assertThat(map.isEmpty()).isTrue();

6. Vérification des éléments d'une MultiValuedMap

Next, let's take a look at the various methods for checking whether a specified key or value exists in our map.

6.1. Check If a Key Exists

To find out whether our map contains a mapping for a specified key, we can use the containsKey method:

assertThat(map.containsKey("vehicles")).isTrue();

6.2. Check If a Value Exists

Next, suppose we want to check if at least one key in our map contains a mapping for a particular value. We can do this using the containsValue method:

assertThat(map.containsValue("orange")).isTrue();

6.3. Check If a Key-Value Mapping Exists

Similarly, if we want to check whether a map contains a mapping for a specific key and value pair, we can use the containsMapping method:

assertThat(map.containsMapping("fruits","orange")).isTrue();

6.4. Check If a Map Is Empty

To check if a map does not contain any key-value mappings at all, we can use the isEmpty method:

assertThat(map.isEmpty()).isFalse;

6.5. Check the Size of a Map

Finally, we can use the size method to get the total size of the map. When a map has keys with multiple values, then the total size of the map is the count of all the values from all keys:

assertEquals(4, map.size());

7. Implementations

The Apache Commons Collections Library also provides multiple implementations of this interface. Let's have a look at them.

7.1. ArrayListValuedHashMap

An ArrayListValuedHashMap uses an ArrayList internally for storing the values associated with each key, so it allows duplicate key-values pairs:

MultiValuedMap map = new ArrayListValuedHashMap(); map.put("fruits", "apple"); map.put("fruits", "orange"); map.put("fruits", "orange"); assertThat((Collection) map.get("fruits")) .containsExactly("apple", "orange", "orange");

Now, it's worth noting that this class is not thread-safe. Therefore, if we want to use this map from multiple threads, we must be sure to use proper synchronization.

7.2. HashSetValuedHashMap

A HashSetValuedHashMap uses a HashSet for storing the values for each given key. Therefore, it doesn't allow duplicate key-value pairs.

Let's see a quick example, where we add the same key-value mapping twice:

MultiValuedMap map = new HashSetValuedHashMap(); map.put("fruits", "apple"); map.put("fruits", "apple"); assertThat((Collection) map.get("fruits")) .containsExactly("apple");

Notice how, unlike our previous example that used ArrayListValuedHashMap, the HashSetValuedHashMap implementation ignores the duplicate mapping.

The HashSetValuedHashMapclass is also not thread-safe.

7.3. Non modifiableMultiValuedMap

Le UnmodifiableMultiValuedMap est une classe de décorateur qui est utile lorsque nous avons besoin d' une instance immuable d'un MultiValuedMap - qui est, il ne devrait pas permettre à d' autres modifications:

@Test(expected = UnsupportedOperationException.class) public void givenUnmodifiableMultiValuedMap_whenInserting_thenThrowingException() { MultiValuedMap map = new ArrayListValuedHashMap(); map.put("fruits", "apple"); map.put("fruits", "orange"); MultiValuedMap immutableMap = MultiMapUtils.unmodifiableMultiValuedMap(map); immutableMap.put("fruits", "banana"); // throws exception }

Et encore une fois, il convient de noter que la modification du put final entraînera une exception UnsupportedOperationException .

8. Conclusion

Nous avons vu différentes méthodes de l' interface MultiValuedMap de la bibliothèque Apache Commons Collections. De plus, nous avons exploré quelques implémentations populaires.

Et, comme toujours, le code source complet est disponible sur Github.