Guava Common Predicates and Functions: A Complete Guide to Functional Utilities
Guava provides the Predicates and Functions utility classes in com.google.common.base that bundle serializable, reusable predicates and function factories for filtering, transforming, and composing logic in Java collections.
The Google Guava library streamlines functional programming patterns in Java through comprehensive utility classes. Understanding Guava's common predicates and functions allows developers to build composable, type-safe operations for collection processing without writing repetitive lambda expressions.
Common Predicates in Guava
The Predicates class defined in guava/src/com/google/common/base/Predicates.java exposes static factory methods for creating standard Predicate implementations. These utilities provide serializable, well-tested alternatives to inline lambda expressions.
Constant and Null-Safe Predicates
Guava offers several fundamental predicates for default logic and null handling:
- alwaysTrue() – Returns a predicate that evaluates to
truefor all inputs. Useful as a default filter or identity element in logical compositions. - alwaysFalse() – Returns a predicate that always evaluates to
false. Often used to short-circuit streams or disable filtering conditionally. - isNull() – Tests whether the input reference is
null. Provides a serializable alternative toObjects::isNull. - notNull() – Tests that the input reference is not
null. ComplementsisNull()for defensive programming.
import com.google.common.base.Predicates;
import java.util.List;
import com.google.common.collect.Collections2;
List<String> items = List.of("a", null, "b", null);
var nonNullItems = Collections2.filter(items, Predicates.notNull());
Logical Composition Methods
Complex filtering logic requires combining simple predicates. The Predicates class provides short-circuiting logical operators:
- and(Iterable<? extends Predicate<? super T>>) / and(Predicate<? super T>...) – Returns a predicate that evaluates to
trueonly if all component predicates returntrue. Short-circuits on the firstfalse. - or(Iterable<? extends Predicate<? super T>>) / or(Predicate<? super T>...) – Returns a predicate that evaluates to
trueif any component predicate returnstrue. Short-circuits on the firsttrue. - not(Predicate) – Negates the result of the supplied predicate, equivalent to
predicate.negate().
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
Predicate<String> isLong = s -> s.length() > 5;
Predicate<String> startsWithA = s -> s.startsWith("A");
// Combines predicates with short-circuiting
Predicate<String> complexFilter = Predicates.and(isLong, Predicates.not(startsWithA));
Equality, Type, and Collection Filtering
For common object comparisons and type checking, Guava provides specialized predicates:
- equalTo(T target) – Returns a predicate testing
Objects.equals(input, target). Handles null references safely. - instanceOf(Class<?>) – Tests whether the input is an instance of the supplied class. Ideal for filtering heterogeneous collections by type.
- **subtypeOf(Class` objects).
- in(Collection<? extends T>) – Checks whether the input is contained in the supplied collection. Provides a serializable replacement for
collection::contains.
import com.google.common.base.Predicates;
import java.util.Set;
Set<String> validCodes = Set.of("OK", "ACTIVE", "PENDING");
var isValidStatus = Predicates.in(validCodes);
Pattern Matching and Predicate Composition
For text processing and complex validation chains:
- containsPattern(String) / contains(Pattern) – Returns a predicate that checks whether a
CharSequencematches the given regular expression. - compose(Predicate, Function<A,? extends B>) – Applies a function to the input first, then evaluates the predicate on the result. Enables validation of derived properties.
import com.google.common.base.Predicates;
import java.util.regex.Pattern;
// Check if string contains digits
var containsDigits = Predicates.containsPattern("\\d+");
// Compose with a function to check user email domains
var hasCompanyDomain = Predicates.compose(
Predicates.equalTo("company.com"),
email -> email.split("@")[1]
);
Common Functions in Guava
The Functions class in guava/src/com/google/common/base/Functions.java supplies static factories for creating Function implementations that transform inputs or extract values.
Identity and String Conversion
Basic transformation utilities include:
- identity() – Returns the identity function (
v -> v). Useful as a placeholder or when an API requires a generic function. - toStringFunction() – Returns a function that calls
Object.toString()on its argument. Provides a serializable alternative toObject::toString.
import com.google.common.base.Functions;
import com.google.common.collect.Lists;
List<Object> objects = List.of(1, 2.5, true);
List<String> strings = Lists.transform(objects, Functions.toStringFunction());
Map-Based Lookup Functions
Guava provides safe, serializable alternatives to direct map access:
- forMap(Map<K,V>) – Creates a function that looks up keys in the map, throwing
IllegalArgumentExceptionif the key is absent. - forMap(Map<K,? extends V>, V defaultValue) – Returns the specified default value when the key is missing instead of throwing an exception.
import com.google.common.base.Functions;
import java.util.Map;
Map<String, Integer> scores = Map.of("Alice", 100, "Bob", 95);
// Throws IllegalArgumentException for missing keys
var strictLookup = Functions.forMap(scores);
// Returns -1 for missing keys
var safeLookup = Functions.forMap(scores, -1);
Advanced Function Composition
For building complex transformation pipelines:
- compose(Function<B,C>, Function<A,? extends B>) – Implements function composition (
g ∘ f). Applies the second function first, then the first function. - constant(E value) – Returns a function that ignores its input and always returns the specified value.
- forPredicate(Predicate) – Wraps a predicate as a
Function<T, Boolean>, adapting predicate logic to function-based APIs. - forSupplier(Supplier) – Returns a function that calls
supplier.get()for every invocation, ignoring the function input.
import com.google.common.base.Functions;
import com.google.common.base.Predicates;
// Compose: first get length, then check if > 5
var lengthCheck = Functions.compose(
Predicates.equalTo(true),
(String s) -> s.length() > 5
);
// Constant function for default values
var alwaysZero = Functions.constant(0);
Summary
- Predicates and Functions in
com.google.common.baseprovide serializable, reusable implementations of common functional interfaces. - Logical composition methods like
Predicates.and(),or(), andnot()enable short-circuiting complex filter conditions without nested lambdas. - Type-safe utilities including
instanceOf(),equalTo(), andin()offer null-safe alternatives to standard Java operations. - Map-based functions in
Functions.forMap()provide explicit error handling and default value support beyond standardMap.get(). - The
compose()methods in both classes facilitate building transformation and validation pipelines without intermediate variables.
Frequently Asked Questions
What is the difference between Guava's Predicates and Java 8's Predicate interface?
Guava's Predicates utility class predates Java 8 and provides static factory methods that return com.google.common.base.Predicate implementations. While Java 8 introduced the standard java.util.function.Predicate interface, Guava's utilities remain valuable for their serializability, null-safe implementations, and logical composition helpers like and() and or() that accept varargs or iterables. Modern code often converts between the two using method references, but Guava's collection utilities specifically expect the Guava Predicate type.
Are Guava's predicate and function implementations serializable?
Yes. According to the source code in guava/src/com/google/common/base/Predicates.java and Functions.java, most factory methods return serializable implementations. This makes them suitable for distributed computing frameworks, caching systems, and Android inter-process communication where lambda expressions (which capture synthetic classes) may cause serialization failures. The documentation explicitly marks these as serializable alternatives to method references like Object::toString or collection::contains.
How do I negate a predicate in Guava?
Use the Predicates.not(Predicate<T>) static method. This returns a predicate that evaluates to the logical negation of the supplied predicate. While Java 8's Predicate.negate() default method provides similar functionality, Guava's not() method accepts null predicates (treating them as always-false) and returns a serializable implementation. For example: Predicates.not(Predicates.isNull()) creates a null-checking predicate equivalent to Predicates.notNull().
When should I use Functions.forMap instead of a lambda calling Map.get()?
Use Functions.forMap() when you need strict error handling or serializability. The two-argument variant returns a default value for missing keys rather than null, preventing NullPointerException in downstream operations. The single-argument variant throws IllegalArgumentException for absent keys, making failures explicit. Additionally, since lambdas are not serializable by default in all contexts, forMap() provides a serializable function suitable for use in Spark, Hadoop, or Android Parcelable contexts where the function must survive serialization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →