This post will discuss various methods to create an immutable set in Java. Immutable Sets have many advantages over their mutable siblings, like they are thread-safe, more memory-efficient, and can be passed to untrusted libraries without any side effects.

Unmodifiable Sets are “read-only” wrappers over other collections. They do not support any modification operations such as add, remove, and clear, but their underlying collection can be changed. Sets that additionally guarantee that no change in the Collection object will ever be visible are referred to as immutable. When we don’t expect to modify a set, it’s a good practice to defensively copy it into an immutable set.

One of the simplest and most widely used ways to create an immutable set in Java is to use the Collections.unmodifiableSet() method, which takes an existing set and returns a view of it that cannot be modified. However, it is unsafe to use as the returned set is only truly immutable if nobody holds a reference to the original collection. This means that we can still modify the original set, which will affect the unmodifiable view as well. The returned set is also inefficient as it still has the overhead of mutable collections, including concurrent modification checks, extra space in hash tables, etc.

 
There are several other ways to create an immutable set in Java, using both built-in methods and external libraries. These are discussed below in detail:

1. Using Set.of() method

Several collection factory methods have been added in Java 9 that allows for easy initialization of immutable collections with specified elements. These factory methods are only available for List, Set, and Map interfaces. The returned collection is structurally immutable, i.e., elements cannot be added, removed, or replaced from the collection. Any modification operation will throw an UnsupportedOperationException.

We can use the Set.of() static factory method to create an immutable set with one or more elements. For example, if we want to create an immutable set with three elements, we can do like:

Download  Run Code

 
This method has the benefit of being straightforward and easy to use. However, it has some limitations: it requires Java 9 or above, it does not accept null values, and it does not preserve the order of the elements. Also, if the contained elements are mutable, it may cause the Collection’s contents to appear to change. For example:

Download  Run Code

2. Using Guava’s ImmutableSet class

Another way to create an immutable set in Java is to use Guava’s ImmutableSet class. This class provides several methods to create an immutable set from an existing set, an array, an iterable, or a builder. Unlike Collections.unmodifiableSet(), which is a view of a separate collection that can still change, an instance of ImmutableSet contains its own private data and will never change.

1. Using ImmutableSet.of() method

The ImmutableSet.of() method returns an immutable set containing the given elements in order. This method has seven overloaded versions, each with a different number of parameters. The last version uses varargs, a special syntax that allows passing an array of elements as a single argument.

Download Code

That’s all about immutable Set in Java.

2. Using ImmutableSet.Builder() method

Guava also provides a Builder for creating an immutable set instance. The ImmutableSet.builder() method returns an ImmutableSet.Builder object, which has methods like add, addAll, build, etc. We can use add() to insert a single element, or addAll() to insert a collection of elements to the builder. Finally, we need to call the build() method that return the immutable set with the elements we added. For example:

Download Code

3. Using ImmutableSet.copyOf() method

The ImmutableSet.copyOf() method returns an immutable set containing the elements of the specified collection, array, or iterator, in the order they appear in it. For example:

Download Code

 
Guava provides more flexibility and functionality over the built-in methods. It creates a new set object that is truly immutable. Even if the contained elements are mutable, it will not cause the Collection’s contents to appear to change. Guava also provides an ImmutableSortedSet class with similar methods returning an immutable “sorted” set containing the elements sorted by their natural ordering. However, Guava is an external library that will result in some overhead. The ImmutableSet class also does not allow null elements and it will throw a NullPointerException if any of its elements is null.