Guava Collections Cookbook

1. Introduction

This cookbook article is organized into small and focused recipes and code snippets for using Guava style collections.

The format is that of a growing list of code examples with no additional explanation necessary – it is meant to keep common usages of the API easy to access during development.

2. The Recipes

downcast a List<Parent> to a List<Child>

- note: this is a workaround for non-covariant generified collections in Java

class CastFunction<F, T extends F> implements Function<F, T> {
    @Override
    public final T apply(final F from) {
        return (T) from;
    }
}
List<TypeParent> originalList = Lists.newArrayList();
List<TypeChild> theList = Lists.transform(originalList, 
    new CastFunction<TypeParent, TypeChild>());

simpler alternative without Guava – involving 2 cast operations

List<Number> originalList = Lists.newArrayList();
List<Integer> theList = (List<Integer>) (List<? extends Number>) originalList;

adding an iterable to a collection

Iterable<String> iter = Lists.newArrayList();
Collection<String> collector = Lists.newArrayList();
Iterables.addAll(collector, iter);

check if collection contains element(s) according to a custom matching rule

Iterable<String> theCollection = Lists.newArrayList("a", "bc", "def");
    boolean contains = Iterables.any(theCollection, new Predicate<String>() {
    @Override
    public boolean apply(final String input) {
        return input.length() == 1;
    }
});
assertTrue(contains);

alternative solution using search

Iterable<String> theCollection = Sets.newHashSet("a", "bc", "def");
boolean contains = Iterables.find(theCollection, new Predicate<String>() {
    @Override
    public boolean apply(final String input) {
       return input.length() == 1;
    }
}) != null;
assertTrue(contains);

alternative solution only applicable to Sets

Set<String> theCollection = Sets.newHashSet("a", "bc", "def");
boolean contains = !Sets.filter(theCollection, new Predicate<String>() {
    @Override
    public boolean apply(final String input) {
        return input.length() == 1;
    }
}).isEmpty();
assertTrue(contains);

NoSuchElementException on Iterables.find when nothing is found

Iterable<String> theCollection = Sets.newHashSet("abcd", "efgh", "ijkl");
Predicate<String> inputOfLengthOne = new Predicate<String>() {
    @Override
    public boolean apply(final String input) {
        return input.length() == 1;
    }
};
String found = Iterables.find(theCollection, inputOfLengthOne);

- this will throw the NoSuchElementException exception:

java.util.NoSuchElementException
	at com.google.common.collect.AbstractIterator.next(AbstractIterator.java:154)
	at com.google.common.collect.Iterators.find(Iterators.java:712)
	at com.google.common.collect.Iterables.find(Iterables.java:643)

- solution: there is an overloaded find method that takes the default return value as an argument and can be called with null for the desired behavior:

String found = Iterables.find(theCollection, inputOfLengthOne, null);

remove all null values from a collection

List<String> values = Lists.newArrayList("a", null, "b", "c");
Iterable<String> withoutNulls = Iterables.filter(values, Predicates.notNull());

create immutable List/Set/Map directly

ImmutableList<String> immutableList = ImmutableList.of("a", "b", "c");
ImmutableSet<String> immutableSet = ImmutableSet.of("a", "b", "c");
ImmutableMap<String, String> imuttableMap = 
    ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3");

create immutable List/Set/Map from a standard collection

List<String> muttableList = Lists.newArrayList();
ImmutableList<String> immutableList = ImmutableList.copyOf(muttableList);

Set<String> muttableSet = Sets.newHashSet();
ImmutableSet<String> immutableSet = ImmutableSet.copyOf(muttableSet);

Map<String, String> muttableMap = Maps.newHashMap();
ImmutableMap<String, String> imuttableMap = ImmutableMap.copyOf(muttableMap);

alternative solution using builders

List<String> muttableList = Lists.newArrayList();
ImmutableList<String> immutableList = 
    ImmutableList.<String> builder().addAll(muttableList).build();

Set<String> muttableSet = Sets.newHashSet();
ImmutableSet<String> immutableSet = 
    ImmutableSet.<String> builder().addAll(muttableSet).build();

Map<String, String> muttableMap = Maps.newHashMap();
ImmutableMap<String, String> imuttableMap = 
    ImmutableMap.<String, String> builder().putAll(muttableMap).build();

3. More Guava Cookbooks

Guava is a comprehensive and fantastically useful library – here’s a few more APIs covered in cookbook form:

Enjoy.

4. Going Forward

As I mentioned in the beginning, I am experimenting with this different format – the cookbook – to try to gather simple common tasks of using Guava Collections in a single place. The focus of this format is simplicity and speed, so most recipes have no additional explanation other than the code example itself.

Finally – I am looking at this as a living document – I’m going to keep adding recipes and examples as I run into them. Feel free to provide more in the comments and I’ll look to incorporate them into the cookbook.

The implementation of all these examples and code snippets can be found in my Guava github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Dev stuff on Google+ - you can follow me there:

GET THE 3 EBOOKS >>
Download the 3 eBooks: "Rest with Spring", "Persistence with Spring" and "Learn HttpClient"
×
Build Your Web App with Spring (and quickly prototype it to 90%)

,

  • Emannuel Silveira

    The downcast for a collection can be done like this:

    Lists.transform(originalList, Functions.identity());

    • http://www.baeldung.com/ Eugen Paraschiv

      Hey Emannuel – thanks for the hint, but I’m not sure that will work – if you use the parent, how are you casting? Here’s the exact test covering this on github – feel free to submit a quick pull request with this and I’d be happy to include it. Cheers,
      Eugen.