Functional Java: Introduction to Pcollections

Table of contents
Reading Time: 4 minutes

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]
view raw

pvector-example

hosted with ❤ by GitHub

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!


Knoldus-blog-footer-image

Written by 

Deepak is a Software Consultant having experince of more than 5 years . He is very enthusiastic towards his work and is a good team player. He has sound knowledge of different technologies which include Java, C++, C, HTML, CSS, Javascript, C# always keen to learn new technologies.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading