Using Guava Functional Programming in Java: Functions, Predicates, and Best Practices

This article explains how to use Guava’s functional programming features in Java, covering Functions and Predicates, providing code examples, discussing potential pitfalls such as overly verbose anonymous classes, and offering guidance on when to prefer functional versus imperative approaches.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Using Guava Functional Programming in Java: Functions, Predicates, and Best Practices

As of JDK7, Java lacks concise functional syntax and relies on verbose anonymous classes; Guava supplies functional utilities that work on JDK5 and later.

Overusing Guava’s functional style can produce long, hard‑to‑read, and inefficient code. The article compares a functional implementation using Function and Predicate with a traditional imperative version.

Functional version:

Function<String, Integer> lengthFunction = new Function<String, Integer>() {
    public Integer apply(String string) {
        return string.length();
    }
};
Predicate<String> allCaps = new Predicate<String>() {
    public boolean apply(String string) {
        return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
    }
};
Multiset<Integer> lengths = HashMultiset.create(
    Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction));

FluentIterable version:

Multiset<Integer> lengths = HashMultiset.create(
    FluentIterable.from(strings)
        .filter(new Predicate<String>() {
            public boolean apply(String string) {
                return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
            }
        })
        .transform(new Function<String, Integer>() {
            public Integer apply(String string) {
                return string.length();
            }
        }));

Imperative version (more concise in this case):

Multiset<Integer> lengths = HashMultiset.create();
for (String string : strings) {
    if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) {
        lengths.add(string.length());
    }
}

The article advises using functional style only when it reduces total lines of code or provides a lazy view that improves performance, and recommends reading Effective Java item 55 and conducting real benchmarks.

Functions and Predicates

Guava defines two core functional interfaces: Function<A,B> (single method B apply(A)) and Predicate<T> (single method boolean apply(T)). Both are expected to be side‑effect‑free and have equality semantics consistent with equals().

Special predicates include CharMatcher for character‑level checks and Range for comparable types, both implementing Predicate.

Operations on Functions

Guava provides utility methods such as Functions.forMap, compose, constant, identity, and toStringFunction. See the Javadoc for full details.

Operations on Predicates

Common predicate factories include instanceOf, in, alwaysTrue, and, or, not, and many others, as listed in the source tables.

Using Functional Programming with Guava Collections

Guava offers a rich set of collection utilities that accept Function or Predicate and return lazy views. Filtering methods are available for Iterable, Iterator, Collection, Set, Map, Multimap, etc.

Transformation methods exist for Iterable, Iterator, Collection, List, Map, Multimap, Table, and more. Example of transforming a list of names into a list of Person objects:

List<String> names;
Map<String, Person> personWithName;
List<Person> people = Lists.transform(names, Functions.forMap(personWithName));

Example of using an EntryTransformer to build a new multimap:

ListMultimap<String, String> firstNameToName =
    Multimaps.transformEntries(firstNameToLastNames,
        new EntryTransformer<String, String, String>() {
            public String transformEntry(String firstName, String lastName) {
                return firstName + " " + lastName;
            }
        });

Additional utilities allow composing functions with ordering, equivalence, suppliers, and futures (e.g., Futures.transform with Function or AsyncFunction).

Overall, Guava’s functional programming features can make code more expressive when used judiciously; developers should weigh readability, line count, and performance before adopting them.

[Translated from Concurrent Programming Network]

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBackend DevelopmentGuavafunctional programmingCollections
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.