Apache Commons Collections Ordonné Carte

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.

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.