This post will discuss about Guava ImmutableList.toImmutableList() method in Java.

Immutable lists are collections of elements that cannot be modified after creation. Immutable lists can offer many benefits, such as thread-safety, performance optimization, and prevention of accidental mutation. However, creating immutable lists in Java can be cumbersome and verbose, especially if you want to create them from existing streams or iterables. That’s where Guava’s ImmutableList.toImmutableList() method comes in handy.

1. Overview of ImmutableList.toImmutableList() method

The ImmutableList.toImmutableList() method returns a Collector that accumulates the input elements into a new ImmutableList. A Collector is an interface that defines how to collect the elements from a stream or an iterable into a result container. The syntax of this method is:

 
The method takes no parameters and returns a Collector of type E, where E is the type of the input elements. The method throws a NullPointerException if any of the input elements is null. The method returns an instance of ImmutableList that cannot be modified directly or indirectly. Any attempt to do so will result in an UnsupportedOperationException.

2. Usage of ImmutableList.toImmutableList() method

To use the ImmutableList.toImmutableList() method, you need to provide a stream or an iterable that contains the elements that you want to include in the immutable list. The stream or iterable can be any type that implements the Stream or Iterable interface, such as List, Set, Queue, Stream, etc. Since this method returns a Collector object that can be used with the Stream.collect() method, if we want to collect a Stream of integers into an ImmutableList, we can write:

Download Code

 
Alternatively, we can use an iterable to create an immutable list. For example, suppose you want to create an immutable list that contains some information about planets in our solar system.

Download Code

 
The elements can be any objects that are not null. Note that if you provide any null element, both methods will throw a NullPointerException at runtime. For example:

Download Code

3. Advantages and Limitations of ImmutableList.toImmutableList()

Using the ImmutableList.toImmutableList() method has many advantages, such as:

  • It is concise and expressive. You can create an immutable list from any stream or iterable in one line of code, without having to create a mutable list first and then wrap it with Collections.unmodifiableList() or ImmutableList.copyOf().
  • It is efficient and optimized. It avoids unnecessary copying and allocation of intermediate lists, and uses a smart algorithm to choose the optimal implementation of ImmutableList based on the size and characteristics of the input.
  • It is consistent and reliable. It always returns an ImmutableList that preserves the insertion order of the elements, regardless of the source or the parallelism of the stream or iterable. It also throws an exception if any of the input elements is null, instead of silently ignoring them or allowing them.

However, using the ImmutableList.toImmutableList() method also has some limitations, such as:

  • It requires Guava as a dependency. If you are not already using Guava in your project, you may need to add it as a dependency to use this method.
  • It may not be compatible with other frameworks or libraries. Some frameworks or libraries may expect or return mutable lists instead of immutable lists, and may not work well with this method. You may need to convert between mutable and immutable lists when using them.

4. Other ways of creating Immutable Lists in Java

There are other ways of creating immutable lists in Java, such as using List.of(), Collections.unmodifiableList(), or ImmutableList.copyOf(). How do they compare with using ImmutableList.toImmutableList()? Here are some differences:

  • List.of() returns an unmodifiable list that contains a fixed number of elements. It preserves the order of the elements, but does not allow null values. It also does not accept streams or iterables as input, and requires you to specify each element as a separate argument.
  • Collections.unmodifiableList() returns a view of a list that cannot be modified, but does not guarantee immutability of the underlying list. If the underlying list is modified, the view will reflect the changes. It also does not preserve the insertion order of the elements, and does not check for null values.
  • ImmutableList.copyOf() returns an immutable list that contains all the elements from a collection or an iterable. It preserves the order of the elements and checks for null values. It creates a copy of the input, which may be inefficient if you already have an immutable list.

5. Conclusion

In this post, we have shown you how to use Guava’s ImmutableList.toImmutableList() method in Java, and explained why it is useful and how it works. We have also compared it with other ways of creating immutable lists in Java, and highlighted some of its advantages and limitations.

If you are interested in learning more about this method, you can check out the Guava official website or its GitHub repository.