This post will discuss create an immutable map from a stream in Java with Guava ImmutableMap.toImmutableMap() method in Java.

There are several ways to create an immutable map from a stream in Java, but one of the most elegant and efficient ones is to use the Guava ImmutableMap.toImmutableMap() method. In this post, we will explore how to use the Guava ImmutableMap.toImmutableMap() method to create an immutable map from a stream in Java, and what are its advantages compared to other methods.

1. Overview of ImmutableMap.toImmutableMap() method

The Guava ImmutableMap.toImmutableMap() method is a static method that returns a Collector that accumulates elements into an ImmutableMap whose keys and values are the result of applying the provided mapping functions to the input elements. The syntax of the Guava ImmutableMap.toImmutableMap() method is as follows:

 
The method accepts two parameters: keyMapper and valueMapper. These are functions that map each element of the stream to a key and a value respectively. The method returns a Collector that can be used with the Stream.collect() method to create an ImmutableMap from the stream. If the keyMapper or valueMapper function returns null for any element of the stream, the toImmutableMap() method will throw a NullPointerException. You need to handle null values explicitly in your mapping functions or filter them out from the stream.

2. Usage of ImmutableMap.toImmutableMap() method

To use the Guava ImmutableMap.toImmutableMap() method, you need to add the Guava library as a dependency to your project. Once you have added Guava to your project, you can import the com.google.common.collect.ImmutableMap class, which contains the toImmutableMap() method. Then, you can simply pass two mapping functions as arguments to the toImmutableMap() method, and use it with the Stream.collect() method on any stream object. For example:

Download Code

 
As you can see, the nameLengths map contains the same elements as the names list, but mapped to different keys and values according to the functions passed to the toImmutableMap() method. However, note that the nameLengths map is immutable, meaning that it cannot be modified after creation. If you try to add or remove an element from it, you will get an UnsupportedOperationException.

3. Advantages of ImmutableMap.toImmutableMap() method

The Guava ImmutableMap.toImmutableMap() method has several advantages compared to other methods of creating an immutable map from a stream in Java. Some of them are:

  • It is simple and concise to use. You only need to pass two mapping functions as arguments and use it with the Stream.collect() method.
  • It is efficient and memory-friendly. It does not create any intermediate collections or copies during the collection process. It only creates one final ImmutableMap object that contains all the elements of the stream.
  • It preserves the encounter order of the stream elements. The entries in the ImmutableMap appear in the same order as they appear in the source stream.
  • It handles duplicate keys gracefully. If the keyMapper function produces duplicate keys for some elements of the stream, the valueMapper function is applied to each occurrence and the values are merged using a merge function. By default, the merge function throws an IllegalArgumentException if duplicate keys are encountered, but you can also provide a custom merge function as a third argument to the toImmutableMap() method.

4. Conclusion

The Guava ImmutableMap.toImmutableMap() method is a powerful and elegant way to create an immutable map from a stream in Java without creating any intermediate collections or copies. It is simple, efficient, ordered, and flexible. However, it also has some drawbacks, such as creating a dependency on the Guava library, not working with primitive streams, and not allowing null keys or values.

For more information about this method, you can check out the Guava official documentation or its GitHub repository.