Pre-1.0 and changing fast
Nothing is released yet. Snapshots of main are published to Maven Central's snapshot repository, and the API
changes between them. Pin a snapshot you have tested.
What Zazr is¶
Zazr gives Java immutable collections and the types that make functional code pleasant: Option, Either,
Try, Validation and Lazy. It is built for Java 25: sealed interfaces, records and pattern matching are part of
its API, not an afterthought. Its design comes from modern Scala's collections and from ZIO.
What it brings¶
-
Collections that state their cost
Every operation whose cost depends on the size documents it, and one page lists them all. You choose a collection for what you do with it, not by guessing.
-
Persistent collections you can build fast
A builder fills a collection in place and hands it over once, so building one in a loop copies nothing.
-
Errors you do not lose
Validationcollects every error instead of stopping at the first, in a list that is never empty. -
Combine up to eight values in one call
zipWithtakes all of them and a function of their values, with no nested tuples to unpack. -
Collections that cannot be empty
On a
NonEmptyVector,head,maxandreducecannot fail, and the return types tell you when that guarantee is lost. -
Pattern matching on results
Option,Either,TryandValidationare sealed interfaces of records, so aswitchover them is checked by the compiler. -
No
nullinside
Values and collections reject it, and absence is an
Option. -
Java interop without copies
asJava()gives a read-onlyjava.utilview in constant time, and the way back does not copy either. -
Names that say what happens
zip,collectAll,catchAll,mapBoth: the vocabulary of ZIO, with no theory to learn first.
A short tour¶
// Validation keeps every error, not the first one
Validation<String, User> user = Validation.zipWith(name(""), age(-1), email("jules"), User::new);
String message = switch (user) {
case Valid(var u) -> "hello " + u.name();
case Invalid(var errors) -> errors.mkString(", ");
};
// "name is blank, age is negative, email has no @"
// zip at any arity up to 8, no Tuple2<Tuple2<A, B>, C>
Option<Integer> sum = Option.zipWith(Option.some(1), Option.some(2), Option.some(3), (a, b, c) -> a + b + c);
// total operations on a collection that cannot be empty
NonEmptyVector<Integer> scores = NonEmptyVector.of(7, 3, 9);
int best = scores.max(Integer::compare);
// a builder instead of repeated append
Vector.Builder<Integer> builder = Vector.newBuilder();
for (int i = 0; i < 1_000; i++) {
builder.add(i);
}
Vector<Integer> numbers = builder.result();
name, age and email each return a Validation<String, ...>; Validation shows them.
Where the ideas come from¶
-
Modern Scala
The Scala 3 collections: the
Vectorbuilder, fast set operations on sorted sets,groupedandslidingthat return collections, and a table of what each operation costs. Sealed interfaces, records andswitchbring Scala's pattern matching to Java. -
ZIO
The operation names (
zipWith,collectAll,forEach,tap,catchAll,mapBoth), one name per operation, and one default sequence with documented costs, asChunkis in ZIO. -
zio-prelude
Validationwith its errors in a non-empty collection,zipto combine independent values, and a non-empty collection whose return types say when it may become empty.
Zazr started as a fork of Vavr. Coming from Vavr? This page lists what changed.
Install¶
JDK 25 or later, no runtime dependencies. Snapshots of main are on Maven Central's snapshot repository.
<repositories>
<repository>
<id>central-portal-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<snapshots><enabled>true</enabled></snapshots>
<releases><enabled>false</enabled></releases>
</repository>
</repositories>
<dependency>
<groupId>com.guizmaii</groupId>
<artifactId>zazr-core</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
com.guizmaii:zazr-test adds property-based testing; see Testing with zazr-test.