Introduction à PCollections

Introduction à PCollections

1. Vue d'ensemble

Dans cet article, nous examineronsPCollections, aJava library providing persistent, immutable collections.

Les structures (collections) dePersistent data ne peuvent pas être modifiées directement pendant l'opération de mise à jour, mais un nouvel objet avec le résultat de l'opération de mise à jour est renvoyé. Ils ne sont pas seulement immuables mais aussi persistants - ce qui signifie queafter modification is performed, previous versions of the collection remain unchanged.

PCollections est analogue et compatible avec le framework Java Collections.

2. Les dépendances

Ajoutons la dépendance suivante à nospom.xml pour que nous puissions utiliser PCollections dans notre projet:


    org.pcollections
    pcollections
    2.1.2

Si notre projet est basé sur Gradle, nous pouvons ajouter le même artefact à notre fichierbuild.gradle:

compile 'org.pcollections:pcollections:2.1.2'

La dernière version peut être trouvée surMaven Central.

3. Structure de la carte (HashPMap)

HashPMap est une structure de données de carte persistante. Il s'agit de l'analogue pourjava.util.HashMap utilisé pour stocker des données de valeur-clé non nulles.

Nous pouvons instancierHashPMap en utilisant des méthodes statiques pratiques dansHashTreePMap. Ces méthodes statiques retournent une instanceHashPMap qui est sauvegardée par unIntTreePMap.

La méthode statiqueempty() de la classeHashTreePMap crée unHashPMap vide qui n'a aucun élément - tout comme en utilisant le constructeur par défaut dejava.util.HashMap:

HashPMap pmap = HashTreePMap.empty();

Il existe deux autres méthodes statiques que nous pouvons utiliser pour créer desHashPMap. La méthodesingleton() crée unHashPMap avec une seule entrée:

HashPMap pmap1 = HashTreePMap.singleton("key1", "value1");
assertEquals(pmap1.size(), 1);

La méthodefrom() crée unHashPMap à partir d'une instancejava.util.HashMap existante (et d'autres implémentations dejava.util.Map):

Map map = new HashMap();
map.put("mkey1", "mval1");
map.put("mkey2", "mval2");

HashPMap pmap2 = HashTreePMap.from(map);
assertEquals(pmap2.size(), 2);

Bien queHashPMap hérite de certaines des méthodes dejava.util.AbstractMap etjava.util.Map, il possède des méthodes qui lui sont propres.

La méthodeminus() supprime une seule entrée de la carte tandis que la méthodeminusAll() supprime plusieurs entrées. Il existe également les méthodesplus() etplusAll() qui ajoutent respectivement des entrées uniques et multiples:

HashPMap pmap = HashTreePMap.empty();
HashPMap pmap0 = pmap.plus("key1", "value1");

Map map = new HashMap();
map.put("key2", "val2");
map.put("key3", "val3");
HashPMap pmap1 = pmap0.plusAll(map);

HashPMap pmap2 = pmap1.minus("key1");

HashPMap pmap3 = pmap2.minusAll(map.keySet());

assertEquals(pmap0.size(), 1);
assertEquals(pmap1.size(), 3);
assertFalse(pmap2.containsKey("key1"));
assertEquals(pmap3.size(), 0);

Il est important de noter que l'appel deput() surpmap lancera unUnsupportedOperationException. Puisque les objets PCollections sont persistants et immuables, chaque opération de modification retourne une nouvelle instance d'un objet (HashPMap) .

Passons maintenant à d'autres structures de données.

4. Structure de la liste (TreePVector and ConsPStack)

TreePVector est un analogue persistant dejava.util.ArrayList tandis queConsPStack est l'analogue dejava.util.LinkedList. TreePVector etConsPStack ont des méthodes statiques pratiques pour créer de nouvelles instances - tout commeHashPMap.

La méthodeempty() crée unTreePVector vide, tandis que la méthodesingleton() crée unTreePVector avec un seul élément. Il existe également la méthodefrom() qui peut être utilisée pour créer une instance deTreePVector à partir de n'importe queljava.util.Collection.

ConsPStack a des méthodes statiques avec le même nom qui atteignent le même objectif.

TreePVector a des méthodes pour le manipuler. Il a les méthodesminus() etminusAll() pour la suppression d'élément (s); lesplus() etplusAll() pour l'ajout d'élément (s).

Lewith() est utilisé pour remplacer un élément à un index spécifié, et lesubList() obtient une plage d'éléments de la collection.

Ces méthodes sont également disponibles enConsPStack.

Examinons l'extrait de code suivant qui illustre les méthodes mentionnées ci-dessus:

TreePVector pVector = TreePVector.empty();

TreePVector pV1 = pVector.plus("e1");
TreePVector pV2 = pV1.plusAll(Arrays.asList("e2", "e3", "e4"));
assertEquals(1, pV1.size());
assertEquals(4, pV2.size());

TreePVector pV3 = pV2.minus("e1");
TreePVector pV4 = pV3.minusAll(Arrays.asList("e2", "e3", "e4"));
assertEquals(pV3.size(), 3);
assertEquals(pV4.size(), 0);

TreePVector pSub = pV2.subList(0, 2);
assertTrue(pSub.contains("e1") && pSub.contains("e2"));

TreePVector pVW = (TreePVector) pV2.with(0, "e10");
assertEquals(pVW.get(0), "e10");

Dans l'extrait de code ci-dessus,pSub est un autre objetTreePVector et est indépendant depV2. Comme on peut l'observer,pV2 n'a pas été modifié par l'opérationsubList(); plutôt un nouvel objetTreePVector a été créé et rempli avec des éléments depV2 d'index 0 à 2.

C'est ce que l'on entend par immutabilité et c'est ce qui se passe avec toutes les méthodes de modification de PCollections.

5. Définir la structure (MapPSet)

MapPSet est un analogue persistant, basé sur une carte, dejava.util.HashSet. Il peut être facilement instancié par des méthodes statiques deHashTreePSet –empty(),from() etsingleton(). Ils fonctionnent de la même manière que celle expliquée dans les exemples précédents.

MapPSet dispose des méthodesplus(),plusAll(),minus() etminusAll() pour manipuler les données d'ensemble. De plus, il hérite des méthodes dejava.util.Set,java.util.AbstractCollection etjava.util.AbstractSet:

MapPSet pSet = HashTreePSet.empty()
  .plusAll(Arrays.asList("e1","e2","e3","e4"));
assertEquals(pSet.size(), 4);

MapPSet pSet1 = pSet.minus("e4");
assertFalse(pSet1.contains("e4"));

Enfin, il y a aussiOrderedPSet - qui maintient l'ordre d'insertion des éléments commejava.util.LinkedHashSet.

6. Conclusion

En conclusion, dans ce rapide tutoriel, nous avons exploré PCollections - les structures de données persistantes analogues aux collections principales disponibles en Java. Bien sûr, les PCollectionsJavadoc fournissent plus d'informations sur les subtilités de la bibliothèque.

Et, comme toujours, le code complet peut être trouvéover on Github.