Disclaimer: This is not an official Google product.


A small Java 8 utilities library (javadoc), with 0 deps (Proto, BigQuery, Guava addons are in separate artifacts).




Add the following to pom.xml:


Add mug-errorprone to your annotationProcessorPaths:


Protobuf utils (javadoc):


Guava add-ons (with SafeQuery and GoogleSql):



Add to build.gradle:

  implementation ''
  implementation ''
  implementation ''


Extracts structured data from string:

new StringFormat("/users/{user}/.{hidden_file_name}")
    .parse(filePath, (user, fileName) -> ...);
new StringFormat("{hour}:{minute}:{second}.{millis}")
    .parse(10:26:30.748, (hour, minute, second, millis) -> ...);

An ErrorProne check is in place to check that the number of lambda parameters and the parameter names match the format string.

This allows you to define StringFormat objects as private class constant, and safely use them many lines away.


Example 1: strip off a prefix if existent:

String httpStripped = Substring.prefix("http://").removeFrom(uri);

Example 2: strip off any scheme prefix from a uri:

String schemeStripped = Substring.upToIncluding(first("://")).removeFrom(uri);

Example 3: split a string in the format of “name=value” into name and value:

Substring.first('=').split("name=value").map((name, value) -> ...);

Example 4: replace trailing “//” with “/” :

Substring.suffix("//").replaceFrom(path, "/");

Example 5: strip off the suffix starting with a dash (-) character :


Example 6: extract a substring using regex :

String quoted = Substring.first(Pattern.compile("'(.*?)'"), 1)

Example 7: find the substring between the first and last curly braces ({) :

String body = Substring.between(first('{'), last('}'))


BiStream streams pairs of objects.

This class closely mirrors JDK Stream API (the few extra methods of “its own” are very straight-forward). If you are familiar with Jdk stream, learning curve is minimal.

Example 1: to concatenate Maps:

import static;

Map<AccountId, Account> allAccounts = concat(primaryAccouunts, secondaryAccounts).toMap();

Example 2: to combine two streams:, responses)

Example 3: to build a Map fluently:

Map<DoctorId, Patient> patientsByDoctorId =, patients)
    .filter((doctor, patient) -> patient.likes(doctor))

Example 4: to build Guava ImmutableListMultimap fluently:

ImmutableListMultimap<ZipCode, Address> addressesByZipCode = BiStream.from(addresses)

Example 5: to a Map into sub-maps:

import static;

Map<Address, PhoneNumber> phonebooks = ...;
Map<State, Map<Address, PhoneNumber>> statePhonebooks = BiStream.from(phonebooks)
    .collect(groupingBy(Address::state, Collectors::toMap))

Example 6: to merge Map entries:

import static;
import static;

Map<Account, Money> totalPayouts =
    .map(Project::payments)  // Stream<Map<Account, Money>>

Example 7: to apply grouping over Map entries:

import static;
import static;
import static;

Map<EmployeeId, Integer> workerHours =
    .map(Project::getTaskAssignments)  // Stream<Map<Employee, Task>>

Example 8: to turn a Collection<Pair<K, V>> to BiStream<K, V>:

BiStream<K, V> stream = RiStream.from(pairs, Pair::getKey, Pair::getValue);

Q: Why not Map<Foo, Bar> or Multimap<Foo, Bar>?

A: Sometimes Foo and Bar are just an arbitrary pair of objects, with no key-value relationship. Or you may not trust Foo#equals() and hashCode(). Instead, drop-in replace your Stream<Pair<Foo, Bar>>/List<Pair<Foo, Bar>> with BiStream<Foo, Bar>/BiCollection<Foo, Bar> to get better readability.

Q: Why not Stream<FooAndBar>?

A: When you already have a proper domain object, sure. But you might find it cumbersome to define a bunch of FooAndBar, PatioChairAndKitchenSink one-off classes especially if the relationship between the two types is only relevant in the local code context.

Q: Why not Stream<Pair<Foo, Bar>>?

A: It’s distracting to read code littered with opaque method names like getFirst() and getSecond().


Example 1: to group consecutive elements in a stream:

List<StockPrice> pricesOrderedByTime = ...;

List<List<StockPrice>> priceSequences =
  , (p1, p2) -> closeEnough(p1, p2), toList())

Example 2: to iterate over Streams in the presence of checked exceptions or control flow:

The Stream API provides forEach() to iterate over a stream, if you don’t have to throw checked exceptions.

When checked exception is in the way, or if you need control flow (continue, return etc.), iterateThrough() and iterateOnce() can help. The following code uses iterateThrough() to write objects into an ObjectOutputStream, with IOException propagated:

Stream<?> stream = ...;
ObjectOutput out = ...;
iterateThrough(stream, out::writeObject);

with control flow:

for (Object obj : iterateOnce(stream)) {
  if (...) continue;
  else if (...) return;

Example 3: to merge maps:

interface Page {
  Map<Day, Long> getTrafficHistogram();

List<Page> pages = ...;

// Merge traffic histogram across all pages of the web site
Map<Day, Long> siteTrafficHistogram =
    .collect(flatteningMaps(groupingBy(day -> day, Long::sum)))


Example 1: to combine two Optional instances into a single one:

Optional<Couple> couple = Optionals.both(optionalHusband, optionalWife).map(Couple::new);

Example 2: to run code when two Optional instances are both present:

Optionals.both(findTeacher(), findStudent()).ifPresent(Teacher::teach);

Example 3: or else run a fallback code block:

static import;

Optional<Teacher> teacher = findTeacher(...);
Optional<Student> student = findStudent(...);
ifPresent(teacher, student, Teacher::teach)             // teach if both present
    .or(() -> ifPresent(teacher, Teacher::workOut))     // teacher work out if present
    .or(() -> ifPresent(student, Student::doHomework))  // student do homework if present
    .orElse(() -> log("no teacher. no student"));       // or else log

Example 4: wrap a value in Optional if it exists:

static import;

Optional<String> id = optionally(request.hasId(), request::getId);

Example 5: add an optional element to a list if present:

static import;


All Optionals utilites propagate checked exception from the the lambda/method references.