Skip to content

Collections

Every Zazr collection is immutable. An operation returns a new collection and shares what it can with the old one, which is never modified.

Each type declares its own methods, with its own return types, and every positional method documents its cost. The complexity page lists them all.

Which one to choose

You need Choose Because
a sequence, by default Vector effectively O(1) get, update, append, prepend, take, drop
a sequence that has at least one element NonEmptyVector head, max, reduce cannot fail
to take a sequence apart head first, or a stack List O(1) prepend, head, tail; switch on Cons and Nil
first in, first out Queue amortised O(1) enqueue and dequeue
a sequence computed on demand, possibly infinite Stream lazy and memoised
a set, by default HashSet effectively O(1) contains, add, remove
a set in insertion order LinkedHashSet a HashSet plus the insertion order, with positional methods
a sorted set TreeSet O(log n) lookups and updates, positional methods in comparator order
a map, by default HashMap effectively O(1) get, put, remove
a map in insertion order LinkedHashMap a HashMap plus the insertion order, with positional methods
a sorted map TreeMap O(log n) lookups and updates, positional methods in key order

What they share

Every collection except NonEmptyVector implements Traversable<T>. It has what works the same way on every type: iterating, size, contains, find, foldLeft, mkString, the conversions such as toVector and stream(), and the asJava() view.

map, filter and the rest are declared by each type, so they return that type.

Two more operations exist on most types:

  • partitionMap splits a collection in one pass, using a function that returns an Either. The sequences and the hash sets have it.
  • The static flatten removes one level of nesting.
Tuple2<List<Integer>, List<String>> split = List.of(1, 2, 3, 4)
    .partitionMap(n -> n % 2 == 0 ? Either.left(n) : Either.right("odd " + n));
Vector<Integer> flat = Vector.flatten(Vector.of(Vector.of(1, 2), List.of(3)));
// split is (List(2, 4), List(odd 1, odd 3)), flat is Vector(1, 2, 3)
Vector<Integer> vector = Vector.of(3, 1, 2);
List<Integer> sortedList = vector.toList().sorted();
HashSet<Integer> set = HashSet.ofAll(vector);
boolean same = Vector.of(1, 2, 3).equals(sortedList);
// List(1, 2, 3), a HashSet of 1, 2, 3, and true

A Vector, List, Queue or Stream equals another of these four when they hold equal elements in the same order. Sets equal sets and maps equal maps. A NonEmptyVector equals only another NonEmptyVector.

Nulls

No collection holds null: adding a null element, key or value throws a NullPointerException. Absence is an Option, which is what find, headOption and Map.get return.

Option<Integer> missing = HashMap.of("a", 1).get("b");
Option<Integer> firstEven = Vector.of(1, 3, 4).find(n -> n % 2 == 0);
// None, Some(4)

Complexity

Each collection's page has a table of its common operations. Complexity puts all the collections side by side and lists every documented method.