org.pcollections/pcollectionsorg.pcollectionshrldcpr/pcollectionspcollections provides Persistent Immutable Collections.
These are collections which cannot be modified, but use structural sharing to make creating updated versions of themselves efficient.
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.
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);
}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);
}