The Java 9 collection factory methods and java 10 copyOf methods add functionalities to create immutableCollections. Before we discuss those methods, let us look at three concepts in collections i.e. View Collection, Unmodifiable collection and unmodifiable view collection.
What is a View Collection?
A view collection does not store elements but instead relies on a backing collection. It provides a few specific methods and delegates to the backing collection for other methods. There are two groups of View Collections. The first group contains wrapper collections and they extend the contract of the collections by making them more specific. For example, Collections.checkedCollection creates a typesafe view of the collection. The second group provides a different representation of the same elements. For example, List.subList provides a view of elements between a startIndex and endIndex. Any changes to the backing collection are reflected in the view and any permitted changes through the view are carried to the backing collection.
What is an Unmodifiable Collection?
An Unmodifiable Collection is a collection that throws an UnsupportedOperationException when any of the mutator methods are called. A mutator method attempts to change the state of the Collection by adding, modifying or deleting entries from it. If the entries of the collection are itself mutable then unmodifiable collection cannot be considered completely mutable. For example, consider an unmodifiable list of addresses. Since the actual address object can be modified outside the collection, the list is considered mutable. Only if all the elements of the list are unmutable, the list is considered effectively unmutable. e.g. java.util.Collections.UnmodifiableList
What is an Unmodifiable View Collection?
An unmodifiable View Collection is an unmodifiable collection that is backed by another collection. It, therefore, provides a read only view into the backing collection. e.g. Collections.unmodifiableCollection. Its mutator methods throw an exception and the accessor methods are delegated to the backing collection.
With that out of the way, let us now look at the new methods added in Java 9 and 10.
collection factory methods in java.util.List
static <E> List<E> of()
Creates an empty immutable list. If we try to add another element to the list, we will get an UnsupportedException
List<String> items = List.of(); //items.add("should throw an error"); // throws java.lang.UnsupportedOperationException
static <E> List<E> of(E e1)
Creates an immutable list with one element. There are methods to add upto 10 elements in the list. i.e. with two elements the method looks like
static <E> List<E> of(E e1, E e2)
With 10 elements it looks like
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
static <E> List<E> of(E... elements)
This method creates an unmodifiableList containing a variable number of arguments.
static <E> List<E> copyOf(Collection<? extends E> coll)
This method was added in Java 10. This method creates an unmodifiableList copy of the given collection. The copy maintains the iteration order.
Collection factory methods in java.util.Map
Map adds new methods similar to the list. Here’s a method that creates an unmodifiable Map with one element.
static <K, V> Map<K, V> of(K k1, V v1)
There are similar method for upto 10 key value pairs.
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries)
This method gets the key value from the entries and adds it to an unmodifiable map. It does not add the actual Entry.
static <K, V> Entry<K, V> entry(K k, V v)
This creates an unmodifiable Entry using the key value pair.
static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map)
This method was added in java 10 and creates a immutable map from another map. Changes made to the original map are not reflected in the immutable map.
- The set interface has methods similar to the List interface with the ‘of()’ methods to create unmodifiable Set from 0 to 10 elements and copyOf method to create an unmodifiable copy.