Collecting a Stream to an Immutable Collection in Java
Streams and Collectors were introduced in Java 8 introduced the concept of Streams. A Stream is a sequence, a sequence of objects. We generate Streams from input sources like Arrays, Lists, etc., and support aggregation operations like filter, map, limit, reduce, etc. We use Streams to pipeline data and ultimately collect it into some form of a Collector. A Collector is nothing but the container used to store the result of the Stream processing. A Collector could be a List, Map, or a Set.
An Immutable collection is a collection whose values we cannot change once created. We do need immutable Collections because many times we can have Collections of data that do not change, i.e., Lookup lists. For example, a list of months in a year or days of the week, etc. Making such lists(which have data that does not change) immutable makes them more memory and space-efficient. They are also inherently thread-safe. Immutable objects, in general, require much less memory than their mutable counterparts.
An object is considered immutable if its state cannot change after it is constructed. After you create an immutable instance of a collection, it holds the same data as long as a reference to it exists.
Methods: Depending on the Java version, multiple methods are available for creating immutable objects as per advancement in versions of java with which we can create Immutable Collections.
- Pre-Java 10
- Creating Stream and collecting it into an unmodifiable structure using the “collectingAndThen”
- Google’s Guava library
- After Java 10
Scenario 1: Pre-Java 10
Method 1: Creating Stream and collecting it into an unmodifiable structure. Before, Java 10 there was no direct way to create an immutable collection in Java. One method was creating a Stream and collecting it into an unmodifiable structure using the “collectingAndThen” method.
Method 2: Using Google’s Guava library. For this, a pre-requisite work is required which is to include the JAR file. The JAR for the Guava library is to download the jar and add it to the build path in eclipse. The Guava Library provides the ImmutableList class. An example of the same is given below.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Note: We can also implement our own version of making an immutable list or map or set.
Scenario 2: Java version 10 and above
Java version 10 introduced functions to create Immutable collections through the Collectors class. We have 3 methods, one for List, one for Set, and one for Map.
Method 1: Using toUnmodifiableList() method. Assume we have a Stream of the first 50 even numbers and create an immutable List from it.
Method 2: Using toUnmodifiableMap() Method
Consider an example of a Books class. The Books object has two parameters namely ‘Id’ and ‘Name’. We will generate a Stream of book Objects. Assume that we have to generate an immutable Map from this collection of Objects. To do so, we use the toUnmodifiableMap() function.
Method 3: Using toUnmodifiableSet() method
Implementation: Creating an unmodifiable Set from a stream to do so, we use the toUnmodifiableSet() function.
Conclusion: Here we have seen how to create Immutable Collections from a Stream in Java. We also saw the different methods used to create the Collections based on the Java version being used.