Collections d'Apache Commons
1. Vue d'ensemble
LeApache Commons Collections library fournit des classes utiles qui complètent le Java Collections Framework.
Dans cet article, nous allons passer en revue l'interfaceOrderedMap, qui étendjava.util.Map.
2. Dépendance Maven
La première chose à faire est d'ajouter la dépendance Maven dans nospom.xml:
org.apache.commons
commons-collections4
4.1
Vous pouvez trouver la dernière version de la bibliothèque sur lesMaven Central repository.
3. Propriétés deOrderedMap
En termes simples, une carte qui implémente l'interfaceOrderedMap:
-
Maintient l'ordre dans son ensemble de clés, bien que l'ensemble ne soit pas trié
-
Peut être itéré dans les deux sens avec les méthodes:firstKey() etnextKey(), oulastKey() etpreviousKey()
-
Peut être parcouru avec unMapIterator (également fourni par la bibliothèque)
-
Fournit des méthodes pour rechercher, modifier, supprimer ou remplacer des éléments
4. Utilisation deOrderedMap
Configurons unOrderedMapde coureurs et leur âge dans une classe de test. Nous utiliserons unLinkedMap - une des implémentations deOrderedMap fournies dans la bibliothèque.
Commençons par configurer des tableaux de coureurs et d'âges que nous utiliserons pour charger la carte et vérifier l'ordre des valeurs:
public class OrderMapUnitTest {
private String[] names = {"Emily", "Mathew", "Rose", "John", "Anna"};
private Integer[] ages = {37, 28, 40, 36, 21};
private LinkedMap runnersLinkedMap;
//...
}
Maintenant, initialisons notre carte:
@Before
public void createRunners() {
this.runnersLinkedMap = new LinkedMap<>();
for (int i = 0; i < RUNNERS_COUNT; i++) {
runners.put(this.names[i], this.ages[i]);
}
}
4.1. Itération avant
Voyons comment l'itérateur avant est utilisé:
@Test
public void givenALinkedMap_whenIteratedForwards_thenPreservesOrder() {
String name = this.runnersLinkedMap.firstKey();
int i = 0;
while (name != null) {
assertEquals(name, names[i]);
name = this.runnersLinkedMap.nextKey(name);
i++;
}
}
Notez que lorsque nous avons atteint la dernière clé, la méthodenextKey() renverra une valeurnull.
4.2. Itération arrière
Maintenant, répétons en arrière, en commençant par la dernière clé:
@Test
public void givenALinkedMap_whenIteratedBackwards_thenPreservesOrder() {
String name = this.runnersLinkedMap.lastKey();
int i = RUNNERS_COUNT - 1;
while (name != null) {
assertEquals(name, this.names[i]);
name = this.runnersLinkedMap.previousKey(name);
i--;
}
}
Une fois que nous atteignons la première clé, la méthodepreviousKey() retournera null.
4.3. MapIterator Exemple
Voyons maintenantuse the mapIterator() method to obtain a MapIterator comme nous montrons comment il préserve l’ordre des coureurs tel que défini dans les tableauxnames etages:
@Test
public void givenALinkedMap_whenIteratedWithMapIterator_thenPreservesOrder() {
OrderedMapIterator runnersIterator
= this.runnersLinkedMap.mapIterator();
int i = 0;
while (runnersIterator.hasNext()) {
runnersIterator.next();
assertEquals(runnersIterator.getKey(), this.names[i]);
assertEquals(runnersIterator.getValue(), this.ages[i]);
i++;
}
}
4.4. Supprimer des éléments
Enfin, voyons commentan element can be removed by index or by object:
@Test
public void givenALinkedMap_whenElementRemoved_thenSizeDecrease() {
LinkedMap lmap
= (LinkedMap) this.runnersLinkedMap;
Integer johnAge = lmap.remove("John");
assertEquals(johnAge, new Integer(36));
assertEquals(lmap.size(), RUNNERS_COUNT - 1);
Integer emilyAge = lmap.remove(0);
assertEquals(emilyAge, new Integer(37));
assertEquals(lmap.size(), RUNNERS_COUNT - 2);
}
5. Implémentations fournies
Actuellement, dans la version 4.1 de la bibliothèque, il existe deux implémentations de l'interfaceOrderedMap -ListOrderedMap etLinkedMap.
ListOrderedMap garde la trace de l'ordre du jeu de touches à l'aide d'unjava.util.List. C'est un décorateur deOrderedMap et peut être créé à partir de n'importe quelMap en utilisant la méthode statiqueListOrderedMap.decorate(Map map).
LinkedMap est basé sur unHashMap et l'améliore en permettant l'itération bidirectionnelle et les autres méthodes de l'interfaceOrderedMap.
Both implementations also provide three methods that are outside the OrderedMap interface:
-
asList() - obtient une liste de typeList<K> (oùK est le type des clés) en préservant l'ordre de la carte
-
get(int index) - récupère l'élément à la positionindex par opposition à la méthodeget(Object o) fournie dans l'interface
-
indexOf(Object o) - obtient l'index de l'objeto dans la carte ordonnée
Nous pouvons convertir lesOrderedMap en unLinkedMap pour utiliser la méthodeasList():
@Test
public void givenALinkedMap_whenConvertedToList_thenMatchesKeySet() {
LinkedMap lmap
= (LinkedMap) this.runnersLinkedMap;
List listKeys = new ArrayList<>();
listKeys.addAll(this.runnersLinkedMap.keySet());
List linkedMap = lmap.asList();
assertEquals(listKeys, linkedMap);
}
Ensuite, nous pouvons vérifier le fonctionnement des méthodesindexOf(Object o) etget(int index) dans l'implémentationLinkedMap:
@Test
public void givenALinkedMap_whenSearchByIndexIsUsed_thenMatchesConstantArray() {
LinkedMap lmap
= (LinkedMap) this.runnersLinkedMap;
for (int i = 0; i < RUNNERS_COUNT; i++) {
String name = lmap.get(i);
assertEquals(name, this.names[i]);
assertEquals(lmap.indexOf(this.names[i]), i);
}
}
6. Conclusion
Dans ce rapide didacticiel, nous avons passé en revue l'interfaceOrderedMap et ses principales méthodes et implémentations.
Pour plus d'informations, voirthe JavaDoc of the Apache Commons Collections library.
Comme toujours, la classe de test complète de cet article contient des cas de test similaires utilisant à la foisLinkedMap etListOrderedMap et peut être téléchargée à partir duGitHub project.