# How to Use Guava Immutable Collections: A Complete Guide to ImmutableList, ImmutableSet, and ImmutableMap

> Master Guava immutable collections like ImmutableList, ImmutableSet, and ImmutableMap. Learn to create thread-safe, null-safe, and unmodifiable data structures with our complete guide.

- Repository: [Google/guava](https://github.com/google/guava)
- Tags: how-to-guide
- Published: 2026-08-10

---

**Use Guava immutable collections by creating immutable instances via static factory methods like `ImmutableList.of()` or `ImmutableList.copyOf()`, or use the `Builder` pattern for complex construction, ensuring thread-safe, null-safe, and unmodifiable data structures.**

The **google/guava** library provides a robust framework for immutable collections that extend the standard Java Collections API with performance and safety guarantees. This guide covers the practical implementation of **Guava immutable collections** based on the actual source code in the `com.google.common.collect` package.

## Why Use Guava Immutable Collections?

Guava immutable collections offer three primary advantages over standard mutable collections:

- **Thread-safety** – No synchronization is required because the data cannot be mutated after creation.
- **Performance** – Operations avoid defensive copying overhead; underlying data structures are stored efficiently.
- **Predictable behavior** – Any attempt to modify the collection throws `UnsupportedOperationException`.

These characteristics make them ideal for constant data, configuration objects, and concurrent environments.

## Core Architecture and Base Classes

All immutable collections in Guava extend the abstract class **`ImmutableCollection`** located at [`guava/src/com/google/common/collect/ImmutableCollection.java`](https://github.com/google/guava/blob/main/guava/src/com/google/common/collect/ImmutableCollection.java). This base class defines common immutable behavior and enforces the contract that elements cannot be added or removed after construction.

Concrete implementations include:
- **`ImmutableList`** – Ordered sequence with indexed access
- **`ImmutableSet`** – Unordered collection of unique elements
- **`ImmutableMap`** – Key-value mappings with unique keys

Each concrete class resides in its respective source file ([`ImmutableList.java`](https://github.com/google/guava/blob/main/ImmutableList.java), [`ImmutableSet.java`](https://github.com/google/guava/blob/main/ImmutableSet.java), [`ImmutableMap.java`](https://github.com/google/guava/blob/main/ImmutableMap.java)) and provides collection-specific factory methods.

## Creating Guava Immutable Collections

### Using Static Factory Methods (`of()` and `copyOf()`)

The simplest way to create immutable collections is through static factory methods that perform null-checks on every element.

**`ImmutableList.of()`** creates instances from explicit elements (optimized for up to 12 arguments) or var-args:

```java
ImmutableList<String> colors = ImmutableList.of("red", "green", "blue");

```

**`ImmutableList.copyOf(Iterable<? extends E>)`** creates an immutable copy from any existing `Iterable` while preserving order:

```java
List<Integer> mutable = new ArrayList<>(Arrays.asList(1, 2, 3));
ImmutableList<Integer> immutable = ImmutableList.copyOf(mutable);

```

Similar factories exist for sets and maps:

```java
ImmutableSet<Integer> primes = ImmutableSet.of(2, 3, 5, 7, 11);
ImmutableMap<String, Integer> ages = ImmutableMap.of("Alice", 30, "Bob", 25);

```

### Using the Builder Pattern

For complex construction logic or conditional additions, use the **`builder()`** method which returns a mutable `Builder` instance. This pattern is defined in [`ImmutableList.java`](https://github.com/google/guava/blob/main/ImmutableList.java) (line 69) and analogous classes:

```java
ImmutableList.Builder<String> builder = ImmutableList.builder();
for (String s : someSource) {
    if (s.startsWith("A")) {
        builder.add(s);
    }
}
ImmutableList<String> aNames = builder.build();

```

The builder can be reused to create multiple immutable instances, making it efficient for batch processing.

### Collecting from Java Streams

For Java 8+ stream processing, use **`toImmutableList()`** (defined in [`guava/src/com/google/common/collect/CollectCollectors.java`](https://github.com/google/guava/blob/main/guava/src/com/google/common/collect/CollectCollectors.java)) to collect results directly:

```java
ImmutableList<Integer> squares = IntStream.rangeClosed(1, 5)
    .map(i -> i * i)
    .boxed()
    .collect(ImmutableList.toImmutableList());

```

## Null Safety and Defensive Programming

All Guava immutable collection factories perform strict **null-checks** on each element. If any element is `null`, the factory immediately throws `NullPointerException` during construction rather than allowing nulls to exist in the supposedly immutable structure. This ensures that once created, the collection is truly immutable and free of null-related surprises.

## Performance Characteristics

According to the source implementation in [`ImmutableCollection.java`](https://github.com/google/guava/blob/main/ImmutableCollection.java), these collections achieve performance through several optimizations:

- **No defensive copying** – When using `copyOf()`, Guava analyzes the input to avoid unnecessary duplication if the source is already immutable.
- **Memory efficiency** – Empty collections return singleton instances (e.g., `ImmutableList.of()` returns the same empty list reference every time).
- **Structural sharing** – Builders use efficient array resizing strategies before finalizing the immutable structure.

## Summary

- Guava immutable collections reside in `com.google.common.collect` and extend `ImmutableCollection`.
- Create instances via **`of()`** for literals, **`copyOf()`** for converting existing collections, or **`builder()`** for complex logic.
- Use **`toImmutableList()`** (and similar collectors) for Stream API integration.
- All factories reject null elements with `NullPointerException` to maintain immutability contracts.
- Attempting modification operations throws `UnsupportedOperationException`.

## Frequently Asked Questions

### What happens if I try to modify a Guava immutable collection?

Any attempt to call mutating methods like `add()`, `remove()`, or `clear()` throws `UnsupportedOperationException`. This is enforced by the base implementation in [`ImmutableCollection.java`](https://github.com/google/guava/blob/main/ImmutableCollection.java) and all concrete subclasses, ensuring runtime protection against accidental modification.

### Can I create a Guava immutable collection containing null elements?

No. All factory methods and builders in `ImmutableList`, `ImmutableSet`, and `ImmutableMap` perform explicit null checks during construction. If you attempt to pass a null element, the method throws `NullPointerException` immediately, preventing nulls from entering the immutable data structure.

### Are Guava immutable collections thread-safe?

Yes. Because the contents cannot change after creation, Guava immutable collections are inherently thread-safe without requiring synchronization. Multiple threads can safely read from the same instance simultaneously, as implemented in the thread-safe publication guarantees of the `ImmutableCollection` hierarchy.

### When should I use `copyOf()` versus the Builder pattern?

Use **`copyOf()`** when you have an existing `Iterable` or collection that you want to convert to an immutable form in a single operation. Use the **Builder pattern** when you need to construct the collection programmatically with loops, conditionals, or multiple steps before finalizing the immutable instance.