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.