Sac de collections Apache Commons

Apache Commons Collections Sac

1. introduction

Dans cet article rapide, nous allons nous concentrer sur l'utilisation de la collectionBag d'Apache.

Lectures complémentaires:

Apache Commons BeanUtils

Apprenez à utiliser Apache Commons BeanUtils pour des opérations courantes.

Read more

Apache Commons IO

Un guide rapide et pratique de la bibliothèque open source Apache Commons IO pour Java, qui couvre bon nombre de ses fonctionnalités les plus connues.

Read more

Introduction au texte Apache Commons

Apprenez à utiliser Apache Commons Text pour des opérations String courantes.

Read more

2. Dépendance Maven

Avant de commencer, nous devons importer les dernières dépendances deMaven Central:


    org.apache.commons
    commons-collections4
    4.1

3. Sacs vs collections

En termes simples,Bag est une collection qui permet de stocker plusieurs éléments avec leur nombre de répétitions:

public void whenAdded_thenCountIsKept() {
    Bag bag = new HashBag<>(
      Arrays.asList(1, 2, 3, 3, 3, 1, 4));

    assertThat(2, equalTo(bag.getCount(1)));
}

3.1. Violations du contratCollection

En lisant la documentation de l'API deBag, nous pouvons remarquer que certaines méthodes sont marquées comme ne respectant pas le contrat de collection Java standard.

Par exemple, lorsque nous utilisons une APIadd() d'une collection Java, nous recevonstrue même si l'élément est déjà dans la collection:

Collection collection = new ArrayList<>();
collection.add(1);
assertThat(collection.add(1), is(true));

La même API d'une implémentation deBag retournera unfalse lorsque nous ajoutons un élément qui est déjà disponible dans la collection:

Bag bag = new HashBag<>();
bag.add(1);

assertThat(bag.add(1), is(not(true)));

Pour résoudre ces problèmes, la bibliothèque d'Apache Collections fournit un décorateur appelé leCollectionBag.. Nous pouvons l'utiliser pour rendre nos collections de sacs conformes au contrat JavaCollection:

public void whenBagAddAPILikeCollectionAPI_thenTrue() {
    Bag bag = CollectionBag.collectionBag(new HashBag<>());
    bag.add(1);

    assertThat(bag.add(1), is((true)));
}

4. Implémentations de sac

Explorons maintenant les différentes implémentations de l'interfaceBag - dans la bibliothèque de collections d'Apache.

4.1. HashBag

Nous pouvons ajouter un élément et indiquer à l'API le nombre de copies que cet élément devrait avoir dans notre collection de sacs:

public void givenAdd_whenCountOfElementsDefined_thenCountAreAdded() {
    Bag bag = new HashBag<>();

    bag.add(1, 5); // adding 1 five times

    assertThat(5, equalTo(bag.getCount(1)));
}

Nous pouvons également supprimer un nombre spécifique de copies ou chaque instance d'un élément de notre sac:

public void givenMultipleCopies_whenRemove_allAreRemoved() {
    Bag bag = new HashBag<>(
      Arrays.asList(1, 2, 3, 3, 3, 1, 4));

    bag.remove(3, 1); // remove one element, two still remain
    assertThat(2, equalTo(bag.getCount(3)));

    bag.remove(1); // remove all
    assertThat(0, equalTo(bag.getCount(1)));
}

4.2. TreeBag

L'implémentation deTreeBag fonctionne comme n'importe quel autre arbre, en conservant en plus la sémantique deBag.

Nous pouvons naturellement trier un tableau d'entiers avec unTreeBag, puis interroger le nombre d'instances de chaque élément individuel dans la collection:

public void givenTree_whenDuplicateElementsAdded_thenSort() {
    TreeBag bag = new TreeBag<>(Arrays.asList(7, 5,
      1, 7, 2, 3, 3, 3, 1, 4, 7));

    assertThat(bag.first(), equalTo(1));
    assertThat(bag.getCount(bag.first()), equalTo(2));
    assertThat(bag.last(), equalTo(7));
    assertThat(bag.getCount(bag.last()), equalTo(3));
}

LeTreeBag implémente une interfaceSortedBag, toutes les implémentations de cette interface peuvent utiliser le décorateurCollectionSortedBag pour se conformer au contrat Java Collections:

public void whenTreeAddAPILikeCollectionAPI_thenTrue() {
    SortedBag bag
      = CollectionSortedBag.collectionSortedBag(new TreeBag<>());

    bag.add(1);

    assertThat(bag.add(1), is((true)));
}

4.3. SynchronizedSortedBag

Une autre implémentation largement utilisée deBag est leSynchronizedSortedBag. Précisément, il s'agit d'un décorateur synchronisé d'une implémentation deSortedBag.

Nous pouvons utiliser ce décorateur avec nosTreeBag (une implémentation deSortedBag) de la section précédente pour synchroniser l'accès à notre sac:

public void givenSortedBag_whenDuplicateElementsAdded_thenSort() {
    SynchronizedSortedBag bag = SynchronizedSortedBag
      .synchronizedSortedBag(new TreeBag<>(
        Arrays.asList(7, 5, 1, 7, 2, 3, 3, 3, 1, 4, 7)));

    assertThat(bag.first(), equalTo(1));
    assertThat(bag.getCount(bag.first()), equalTo(2));
    assertThat(bag.last(), equalTo(7));
    assertThat(bag.getCount(bag.last()), equalTo(3));
}

Nous pouvons utiliser une combinaison d'API -Collections.synchronizedSortedMap() etTreeMap – pour simuler ce que nous avons fait ici avecSynchronizedSortedBag.

5. Conclusion

Dans ce court didacticiel, nous avons découvert l’interfaceBag et ses différentes implémentations.

Comme toujours, le code de cet article se trouveover on GitHub.