Today we will talk about Pcollections which is nothing but a persistent and immutable Java collections library. Immutability has become a buzz word nowadays which is Okay, right?
When we talk about immutability and collections at the same time we don’t have a way out since Java collections framework is not capable enough to produce immutable and persistent collections directly. However, there are ways with which we can make collections unmodifiable in Java collections, but what if we already have a library or something which makes our collections persistent and immutable at the same time from the very beginning i.e once the collection is instantiated, would not that be great, of course would, for the same Pcollections comes out for the rescue which will make collections persistent and immutable. We will see various examples, How can we instantiate our collections in later part of the article.
Let’s first understand if there is a difference between persistent and immutability. Immutability means, once an object in intantiated it is unmodifiable i.e cannot be changed or modified in any way but persistent data structure is a data structure that always preserves the previous version of itself when it is modifed. Such data structure are effectively immutable, as it will not update the original object but create a new instance with updated structure(object) for that matter.
Why Immutable collections?
Now, why are we talking so much about immutable collections, first it is a functional way doing things as immutability is directly related to functional programming, second it provides thread safety and you do not have to worry about thread synchronization and eveything.
Let’s talk about Pcollections in detail.
How to use Pcollections in your project?
1. If you are using Maven
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependency> | |
<groupId>org.pcollections</groupId> | |
<artifactId>pcollections</artifactId> | |
<version>3.1.0</version> | |
</dependency> |
Note- Please check for latest version on Maven central repository
2. If you are using Gradle
compile 'org.pcollections:pcollections:3.1.0'
Let’s talk about the collections one by one
Pvector
First, we have TreePvector – TreePVector provides a PVector implementation which similar to Java’s ArrayList with some advantages of course. Let’s see TreePvector in detail.
Create an empty collections.
// Create an empty Pvector collection. PVector pVector = TreePVector.empty();
Create a PVector collection with single element.
// Create PVector with single element PVector pVector2 = TreePVector.singleton("Deeps"); System.out.println(pVector2);
Create a Pvector collection
You can create a Pvector using static factory method from( Collection<? extends E> list) which takes collections in the argument.
PVector pVector1 = TreePVector.from(existing collections);
Example - List students = Arrays.asList("Deepak", "Bhawna", "Charmy", "Vinisha"); // Create a Pvector collection. PVector pVector1 = TreePVector.from(students);
Now, let’s talk about the commonly used method with Pvector
plus, plusAll, minus, minusAll, singleton
Above methods are widely used with Pvector
plus – plus would return a new Pvector object with appended element, plus takes E type argument, since everything is immutable under Pcollections it would return a new object and existing object would remain untouched and unaffected.
Example –
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
List students = Arrays.asList("Deepak", "Bhawna", "Charmy", "Vinisha"); | |
// Create a Pvector collection. | |
PVector pVector1 = TreePVector.from(students); | |
pVector1.plus("Rahul"); | |
System.out.println(pVector1); | |
// Output – [Deepak, Bhawna, Charmy, Vinisha] |
Wait, where did Rahul go, we also added Rahul element in the list but it was never modified because Pvector is immutable, so in order to see the change we will have to hold it in a new reference.
Example –
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
List students = Arrays.asList("Deepak", "Bhawna", "Charmy", "Vinisha"); | |
// Create a Pvector collection. | |
PVector pVector1 = TreePVector.from(students); | |
PVector rahul = pVector1.plus("Rahul"); | |
System.out.println(pVector1); // Output – [Deepak, Bhawna, Charmy, Vinisha] | |
System.out.println(rahul); // Output – [Deepak, Bhawna, Charmy, Vinisha, Rahul] | |
plusAll – plusAll works just like plus to add items to the collection. However, it takes a collection in the argument. It also returns the new Pvector object with collection added to existing collection.
Example - //plus-all PVector plusAll = pVector1.plusAll(rahul); //where rahul is an existing collection. System.out.println(plusAll);
minus – minus is just opposite of plus where we would like to remove an element from the collection. Also, whenever we use minus a new object would be returned.
Example - //minus PVector minus = pVector1.minus("Charmy"); System.out.println(minus);
minusAll – minusAll method is used to delete a list of items from a collection, it takes collection as an argument and removed all the items from the real collection.
Example - //minus-all PVector minusAll = plusAll.minusAll(students); System.out.println(minusAll);
where student is an existing collection of items and all these items will be removed from original collection which is plusAll in our example.
Refer to Javadoc for more details
https://static.javadoc.io/org.pcollections/pcollections/3.1.0/org/pcollections/PVector.html
PSet
HashTreePSet provides a Pset implementation which is similar to Java’s HashSet with some advantage like persistent and immutable collection. Let’s see PSet in detail.
Create an empty collections.
// Create an empty PSet collection. PSet pSet = HashTreePSet.empty(); // Printing empty collection. System.out.println(pSet);
Create a PSet collection
You can create a PSet using static factory method from( Collection<? extends E> list) which takes collections in the argument.
PSet pSet = HashTreePSet.from(existing collections);
Example - List list = Arrays.asList("Vinisha","Vinisha","Deepak","Deepak","Ayush","Ayush"); PSet pSet1 = HashTreePSet.from(list); System.out.println(pSet1); // Output - [Ayush, Deepak, Vinisha]
Now, let’s talk about the commonly used method with PSet
plus, plusAll, minus, minusAll, singleton
Above methods are widely used with PSet
All these methods works exactly the same as Pvector. So whatever example we saw previously can be used for Pset as well. So, I am not going to share the example. The only difference between Pset and PVector is Pset will not take duplicate items just like Java’s Set and PVector will take duplicate items just like Java’s List.
PMap
HashTreePMap provides a PMap implementation which is similar to Java’s HashMap and comes with some advantage of couse as it’s a part of Pcollections. Let’s see Pmap in details.
Create an empty Map.
// Create an empty PMap. PMap pMap = HashTreePMap.empty(); // Printing empty Map. System.out.println(pMap);
Create a Pmap with existing Map
// Create a Map with existing map Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "Deepak"); map.put(2, "Deeps"); PMap pMap1 = HashTreePMap.from(map); System.out.println(pMap1);
We can create a Pmap using the factory method from() which takes a Map as an argument.
Create a Pmap with single item.
// Create a PMap with single item PMap<String, String> pMap2 = HashTreePMap.singleton("1", "Deepak"); System.out.println(pMap2);
Add a key, value pair to the Pmap
// Add a key,value pair to the PMap PMap<String, String> plus = pMap2.plus("2", "Deeps"); System.out.println(plus);
The most commonly used methods with PMap are as follows.
plus – add a new pair to PMap
plusAll – can add multiple pairs from a Pmap as it takes a Map as an argument.
clear – clear will remove all the pair from PMap
minus – remove the pair from PMap
minusAll – can remove multiple pairs from a Pmap as it takes a Map as an argument.
Refer to Javadoc for more details
https://static.javadoc.io/org.pcollections/pcollections/3.1.0/org/pcollections/PMap.html
So, if you really want to leverage immutable and persistent collections you shoule be using Pcollections because immutable and persistent collection of course, has some advantages which we have discussed already. If you loved the article, please give it a thumbs up and if you have queries please let me know in comments. Also, there is a project on github with all the examples. Keeping reading!