An Overview of Google Guava: Immutable Collections, New Collection Types, and Utility Classes
This article introduces Google Guava, covering its core purpose, how to add the library via Maven, the benefits and creation methods of immutable collections, the additional collection types such as Multiset, Multimap, BiMap, Table, and ClassToInstanceMap, as well as Guava's helper utilities for JDK collections, primitive types, strings, and the Stopwatch timing class, each illustrated with code examples and links to source repositories.
Google Guava Overview
Guava is a core Java library from Google that provides new collection types (e.g., Multiset, Multimap), immutable collections, a graph library, and utilities for concurrency, I/O, hashing, caching, primitives, and strings. It is widely used in Google projects and many other companies.
GitHub repository: https://github.com/google/guava
Official documentation: https://github.com/google/guava/wiki
Maven dependency example:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>Immutable Collections and Objects
Creating immutable copies of objects is a defensive programming technique offering safety for untrusted libraries, thread‑safety, memory efficiency, and constant semantics. Guava immutable collections reject null values and throw exceptions when nulls are encountered.
Immutable collections can be created via:
Copy‑of methods, e.g., ImmutableSet.copyOf(set)
Of methods, e.g., ImmutableSet.of("a", "b", "c") or ImmutableMap.of("a", 1, "b", 2)
Builder pattern
Guava provides immutable versions for all standard JDK collection interfaces:
Interface
JDK/Guava
Immutable Version
Collection
JDK
ImmutableCollection
List
JDK
ImmutableList
Set
JDK
ImmutableSet
SortedSet/NavigableSet
JDK
ImmutableSortedSet
Map
JDK
ImmutableMap
SortedMap
JDK
ImmutableSortedMap
Multiset
Guava
ImmutableMultiset
SortedMultiset
Guava
ImmutableSortedMultiset
Multimap
Guava
ImmutableMultimap
ListMultimap
Guava
ImmutableListMultimap
SetMultimap
Guava
ImmutableSetMultimap
BiMap
Guava
ImmutableBiMap
ClassToInstanceMap
Guava
ImmutableClassToInstanceMap
Table
Guava
ImmutableTable
Example immutable collection source code: https://github.com/main/java/com/wmx/guava/ImmutableCollectionTest.java
New Collection Types in Guava
Guava introduces several collection types not present in the JDK, designed to coexist peacefully with standard collections.
Multiset (Repeated Elements)
Multiset allows duplicate elements and is backed by a HashMap . Implementations include HashMultiset , LinkedHashMultiset , and TreeMultiset .
Source: https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/MultisetTest.java
Multimap (Multiple Values per Key)
Guava’s Multimap simplifies mapping a key to multiple values, replacing patterns like Map<K, List<V>> or Map<K, Set<V>> . Implementations include:
Multimap
Key Implementation
Value Implementation
ArrayListMultimap
HashMap
ArrayList
HashMultimap
HashMap
HashSet
LinkedHashMultimap
LinkedHashMap
LinkedHashSet
TreeMultimap
TreeMap
TreeSet
ImmutableListMultimap
ImmutableMap
ImmutableList
ImmutableSetMultimap
ImmutableMap
ImmutableSet
Source: https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/MultimapTest.java
BiMap (Bidirectional Map)
BiMap provides a one‑to‑one mapping between keys and values, avoiding the need for two separate maps. Implementations include HashBiMap , ImmutableBiMap , EnumBiMap , and EnumHashBiMap .
Source: https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/BiMapTest.java
Table (Two‑Dimensional Map)
Table models a map of maps, e.g., Map<RowKey, Map<ColumnKey, Value>> . Implementations include HashBasedTable , TreeBasedTable , ImmutableTable , and ArrayTable .
Source: https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/TableTest.java
ClassToInstanceMap
This map allows keys of various types to be associated with instances of those types. Implementations are MutableClassToInstanceMap and ImmutableClassToInstanceMap .
Source: https://github.com/wangmaoxiong/src/main/java/com/wmx/guava/ClassToInstanceMapTest.java
JDK Collection Helper Utilities
Guava adds static utility classes that complement java.util.Collections , such as Collections2 , Lists , Sets , Maps , Queues , Multisets , Multimaps , Tables , etc.
Examples: Lists demo: https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/ListsTest.java Sets demo: https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/SetsTest.java
JDK Primitive Helper Utilities
Guava provides utility classes for primitive types, e.g., Bytes , Shorts , Ints , Longs , Floats , Doubles , Chars , and Booleans . Sample source code for each type is linked in the article.
JDK String Helper Utilities
The Strings class offers basic string utilities. Joiner concatenates elements of an Iterable , Iterator , or array. Splitter divides a CharSequence . CharMatcher matches characters such as digits or whitespace.
Stopwatch (Timing Utility)
Guava’s Stopwatch is a convenient timing tool compared to Spring’s core or Apache Commons Lang3 stopwatches. It is not thread‑safe.
/**
* Stopwatch createStarted(): creates and starts a new stopwatch using System#nanoTime.
* Stopwatch createUnstarted(): creates a new stopwatch without starting it.
* long elapsed(TimeUnit desiredUnit): returns elapsed time in the requested unit.
* boolean isRunning(): true if started and not stopped.
* void reset(): resets elapsed time to zero and stops.
* void start(): starts the stopwatch; throws IllegalStateException if already running.
* void stop(): stops the stopwatch; further reads return the fixed duration.
* String toString(): returns a human‑readable representation, e.g., "2.588 s".
*/
@Test
public void testStopwatch() throws InterruptedException {
SecureRandom secureRandom = new SecureRandom();
Stopwatch stopwatch = Stopwatch.createStarted();
int nextInt = secureRandom.nextInt(2000);
System.out.println("Task 1 estimated time: " + nextInt);
TimeUnit.MILLISECONDS.sleep(nextInt);
System.out.println("\tTask 1 actual time: " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + "(ms)");
stopwatch.reset().start();
nextInt = secureRandom.nextInt(4000);
System.out.println("Task 2 estimated time: " + nextInt);
TimeUnit.MILLISECONDS.sleep(nextInt);
System.out.println("\tTask 2 actual time: " + stopwatch.toString());
stopwatch.reset().start();
nextInt = secureRandom.nextInt(3000);
System.out.println("Task 3 estimated time: " + nextInt);
TimeUnit.MILLISECONDS.sleep(nextInt);
System.out.println("\tTask 3 actual time: " + stopwatch.stop().toString());
}The article concludes with a call to share the content and join the author’s community groups.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.