org.pcollections

What is it

pcollections provides Persistent Immutable Collections.

These are collections which cannot be modified, but use structural sharing to make creating updated versions of themselves efficient.

Why use it

Persistent collections are useful when you want a data aggregate that is immutable but will require multiple updates over the runtime of the program.

pcollections is unique in the ecosystem of persistent collection libraries in that its types directly extend the Java Collections Framework. Its PVector is a subtype of java.util.List, its PMap is a subtype of java.util.Map, and so on.

There are definite cons to that - having a remove method that does nothing is unideal - but there are also pros. There is no conversion cost when interacting with the numerous APIs that expect java.util.* types.

Getting Started

Basic Usage

import org.pcollections.PVector;
import org.pcollections.TreePVector;

void main() {
    var names = TreePVector.empty();
    var names2 = names.plus("Mumenstallu");
    var names3 = names2.plus("Snufkin");
    
    System.out.println(names);
    System.out.println(names2);
    System.out.println(names3);
}

Many updated versions

import org.pcollections.PVector;
import org.pcollections.TreePVector;

void main() {
    PVector<PVector<Integer>> allVersions = TreePVector.empty();
    PVector<Integer> numbers = TreePVector.empty();
    
    for (int i = 0; i < 10000; i++) {
        numbers = numbers.plus(i);
        allVersions = allVersions.plus(numbers);
    }
    
    System.out.println(allVersions.size());
    
    // Every version is still valid
    System.out.println(allVersions.get(2));
    System.out.println(allVersions.get(4));
    System.out.println(allVersions.get(100));
    
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    System.out.println(total);
}

<- Index