Groovy™ Processing Nulls In Lists
Published: 2023-02-06 12:00AM (Last updated: 2026-08-03 10:00AM)
This article by Shubhra Srivastava looks at processing lists containing nulls in Java. Let’s look at doing the same in Groovy. Shubhra’s article covered both mutating the list in place and producing a new list, so we’ll cover both cases.
Libraries covered
Shubhra’s article examined "out-of-the-box" Java and some other collections libraries. We’ll look at using those same libraries with Groovy, but we’ll cover Eclipse Collections too.
In summary, we’ll cover:
-
"Out-of-the-box" Groovy (which includes JDK functionality)
-
Guava which provides a number of extensions to the JDK collections ecosystem. In particular, it has immutable collections, new collection types like multisets and bidirectional maps and various powerful extensions and utilities.
-
Apache Commons Collections which extends upon the JDK collections framework adding some new types like bidirectional maps and bags as well as providing many comparator and iterator implementations. The library was designed to fill gaps in the JDK offerings and while some of those gaps in the JDK have now been filled by the JDK itself, Commons Collections still contains much useful functionality.
-
Eclipse Collections which comes with many container types including immutable collections, primitive collections, bimaps, multimaps and bags as well as numerous utility methods. It focuses on reduced memory footprint and efficient containers. It might be particularly of interest if you need primitive collections, immutable collections or some more exotic collection types like bag or bidirectional maps.
Mutating a list to remove its nulls
Groovy
With Groovy, we can follow Java’s lead and use removeIf or use Groovy’s removeAll.
In either case, we can use a method reference, closure syntax or lambda syntax
to capture the desired non-null constraint.
var list = ['A', null, 'B', null, 'C']
list.removeIf(Objects::isNull)
assert list.size() == 3
var list = ['A', null, 'B', null, 'C']
list.removeAll(s -> s == null)
assert list.size() == 3
Guava
var list = ['A', null, 'B', null, 'C']
Iterables.removeIf(list, Predicates.isNull())
assert list.size() == 3
Apache Commons Collections
var list = ['A', null, 'B', null, 'C']
CollectionUtils.filter(list, PredicateUtils.notNullPredicate())
assert list.size() == 3
Eclipse Collections
var list = Lists.mutable.of('A', null, 'B', null, 'C')
list.withoutAll([null])
assert list.size() == 3
Producing a new list without nulls
Groovy
We can use Java streams as per the original article or avoid streams and use Groovy’s findAll method:
assert ['A', null, 'B'].stream().filter(Objects::nonNull).toList().size() == 2
assert ['A', null, 'B'].findAll(Objects::nonNull).size() == 2
In this case, we can also use findAll and grep no-arg shortcuts.
These shortcuts follow Groovy truth
which will remove nulls but also empty Strings and zeros. This may or may not be what we want.
assert ['A', null, 'B'].findAll().size() == 2
assert ['A', null, 'B'].grep().size() == 2
assert ['A', null, 'B', '', 0].findAll().size() == 2
assert ['A', null, 'B', '', 0].grep().size() == 2
Groovy also has the findResults method which specifically looks
for non-null results rather than applying Groovy truth:
assert ['A', null, 'B'].findResults{ it }.size() == 2
assert ['A', null, 'B'].findResults().size() == 2 // (1)
assert ['A', null, 'B', '', 0].findResults().size() == 4 // (1)
-
The no-arg shortcut variants are available from Groovy 4.0.9 onwards.
Each of these builds the whole list eagerly. From Groovy 5,
and further enhanced in Groovy 6, the
long-standing eager methods have lazy counterparts — collecting,
collectingMany, findingAll, findingResults and friends — which
return an Iterator rather than a List. The no-arg shortcut is
available here too:
assert ['A', null, 'B'].iterator().findingResults().toList() == ['A', 'B']
Laziness matters when the source is large or unbounded and you only want the first few non-null results — nothing beyond those is ever computed:
var firstFour = (1..Integer.MAX_VALUE).iterator()
.findingResults{ it % 3 == 0 ? it : null }
.take(4).toList()
assert firstFour == [3, 6, 9, 12]
Call toList() when you do want the whole thing.
Guava
assert Iterables.filter(['A', null, 'B'], Predicates.notNull()).size() == 2
Apache Commons Collections
assert CollectionUtils.select(['A', null, 'B'], PredicateUtils.notNullPredicate()).size() == 2
Eclipse Collections
assert Lists.mutable.of('A', null, 'B').select(Predicates.notNull()).size() == 2
Other null related functionality
Before concluding, we should mention some other Groovy functionality related to null.
Groovy’s @NullCheck AST transform automatically adds null checking into your own
classes, methods, and constructors — see the
documentation.
Groovy 6 adds takeIf, which returns the receiver when a predicate holds and null
otherwise. It reads naturally alongside the Elvis operator, turning a test into a
value:
var url = 'example.com'
assert (url.takeIf{ it.startsWith('http') } ?: "https://$url") == 'https://example.com'
More substantially, Groovy 6 moves null handling from a runtime concern to a
compile-time one. The NullChecker type-checking extension catches null
dereferences, unsafe assignments and missing null checks before the code runs, and
in strict mode it infers nullness from flow without needing any annotations at
all. The companion post
Compile-time null safety for Groovy
covers it, along with the dynamic idioms — safe navigation, Elvis, Groovy truth —
that this post has been leaning on throughout.
Further Information
-
Java – Remove all nulls from a List (original and javacodegeeks)
-
Eclipse Collections (website and github site)
-
Guava (user guide)
-
Apache Commons Collections (website)
Have fun processing nulls with Groovy!