Java 9 changes for Collections

n this post, we are going to discuss one more Java SE 9 New Feature: “Factory Methods for Immutable List, Set and Map” with some simple and suitable examples.

Java SE 8: Empty Immutable List, Set and Map

In Java SE 8 and earlier Versions, if we want to create an empty Immutable or Unmodifiable List, we should use Collections class utility methods: unmodifiableList,unmodifiableSet and unmodifiableMap as shown below:

Example:-

 List<String> emptyList = new ArrayList<>(); List<String> immutableList = Collections.unmodifiableList(emptyList); Set<String> emptySet = new HashSet<>(); Set<String> immutableSet = Collections.unmodifiableSet(emptySet); Map<Integer,String> emptyMap = new HashMap<>(); Map<Integer,String> immutableEmptyMap = Collections.unmodifiableMap(emptyMap);

NOTE:- Diamond Operator does NOT work in Java SE 6 and earlier versions. Rest of the code is same for all Java versions.

Here we can observe that to create an empty Immutable List,Set and Map. we need to do lot of stuff as shown above. It is very tedious and verbose thing right. Let us see the same thing in Java SE 9 now.

Java SE 9: Immutable Empty List, Set and Map

If we go through the Java SE 9 List,Set and Map API, we can find the below method signature in List interface.

 static <E> List<E> of() static <E> Set<E> of() static <K,V> Map<K,V> of()

It is used to create an empty Immutable List (a List with zero elements).

Example:-

 List<String> immutableList = List.of(); Set<String> immutableSet = Set.of(); Map<Integer,String> emptyImmutableMap = Map.of()

Java SE 9 has introduced two sets of useful overloaded methods of Map.

  • Map.of()
  • Map.ofEntries()

Java SE 8: Non-Empty Immutable List, Set and Map

Now we will see how to create Non-Empty Immutable List in Java SE 8 and earlier versions.

Example:-

 List<String> list = new ArrayList<>(); list.add("one"); list.add("two"); list.add("three"); List<String> immutableList = Collections.unmodifiableList(list);Set<String> nonemptySet = new HashSet<>(); nonemptySet.add("one"); nonemptySet.add("two"); nonemptySet.add("three"); Set<String> immutableSet = Collections.unmodifiableSet(nonemptySet);Map<Integer,String> nonemptyMap = new HashMap<>(); nonemptyMap.put(1,"one") nonemptyMap.put(2,"two") nonemptyMap.put(3,"three") Map<Integer,String> immutableNonEmptyMap = Collections.unmodifiableMap(nonemptyMap);

Here also we can observe that to create a non-empty Immutable List, Set,Map. we need to do lot of stuff and very tedious and verbose steps. Let us see the same thing in Java SE 9 now.

Java SE 9: Non-Empty Immutable List

To overcome those shortcomings, Java SE 9 has introduced the following useful overloaded methods.

These useful methods are used to create a new Immutable List with one element to 10 elements:

List:static <E> List<E> of(E e1)static <E> List<E> of(E e1,E e2)	static <E> List<E> of(E e1,E e2,E e3)static <E> List<E> of(E e1,E e2,E e3,E e4)static <E> List<E> of(E e1,E e2,E e3,E e4,E e5)	static <E> List<E> of(E e1,E e2,E e3,E e4,E e5,E e6)	static <E> List<E> of(E e1,E e2,E e3,E e4,E e5,E e6,E e7)	static <E> List<E> of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8)	static <E> List<E> of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8,E e9)	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)Set:static <E> Set<E> of(E e1)static <E> Set<E> of(E e1,E e2)	static <E> Set<E> of(E e1,E e2,E e3)static <E> Set<E> of(E e1,E e2,E e3,E e4)static <E> Set<E> of(E e1,E e2,E e3,E e4,E e5)	static <E> Set<E> of(E e1,E e2,E e3,E e4,E e5,E e6)	static <E> Set<E> of(E e1,E e2,E e3,E e4,E e5,E e6,E e7)	static <E> Set<E> of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8)	static <E> Set<E> of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8,E e9)	static <E> Set<E> of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8,E e9,E e10)Map: static <K,V> Map<K,V> of(K k1, V v1) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10)

The following is a Var-Args method (Variable Number of arguments method):

static <E> List<E> of(E... elements)  static <E> Set<E> of(E... elements)  static <K,V> Map<K,V> of(K k1, V v1)

Example:-

 List<String> immutableList = List.of("one","two","three"); Set<String> immutableSet = Set.of("one","two","three") Map<Integer,String> nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")If we try to perform Add/Delete/Update operations on them, we will get UnsupportedOperationException as shown below:immutableList.add("four")|  java.lang.UnsupportedOperationException thrown: |        at ImmutableCollections.uoe (ImmutableCollections.java:68)|        at ImmutableCollections$AbstractImmutableList.add (ImmutableCollections.java:74)|        at (#2:1)They don’t allow null elements.immutableList = List.of("one","two","three", null)|  java.lang.NullPointerException thrown: |        at Objects.requireNonNull (Objects.java:221)|        at ImmutableCollections$ListN. (ImmutableCollections.java:179)|        at List.of (List.java:859)|        at (#4:1)If we try add null elements, we will get UnsupportedOperationException as shown below:immutableList.add(null)|  java.lang.UnsupportedOperationException thrown: |        at ImmutableCollections.uoe (ImmutableCollections.java:68)|        at ImmutableCollections$AbstractImmutableList.add (ImmutableCollections.java:74)|        at (#3:1)

They are serializable if all elements are serializable.

Immutable Map.ofEntries() Utility

As we know, Java SE 9 has introduced two sets of Map Utility methods to create Immutable Map: of and ofEntries. We have already discussed about Map.of() methods in the previous sections. In this section, we will discuss about “How to use Map.ofEntries() methods” to create empty or non-empty Maps.

Map.ofEntries() methods are used to create Immutable or Unmodifiable Maps using Entries.

If we go through the Java SE 9 Map API, we can find the below utility methods in Map interface.
Empty Map API Utility

static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)

This var-args method is useful to create an Immutable Map with zero or one or more elements using Entries. We should use Map.entry() utility method to create Entries. Please refer next section to understand this Map.entry() method.

Empty Map Example:-

jshell> Map<Integer,String> emptyImmutableMap = Map.ofEntries()emptyImmutableMap ==> {}

This useful method is used to create a new Immutable Map with zero element using Entries.

Non-Empty Map Example:-

import static java.util.Map.entryjshell> Map<Integer,String> emptyImmutableMap = Map.ofEntries(entry(1,"one"),   ...> entry(2,"two"), entry(3,"three"))emptyImmutableMap ==> {1=one, 2=two, 3=three}

This useful method is used to create a new Immutable Map with one or more elements using Entries.

Java SE 9: Immutable Map.entry() Utility

As we discussed in the previous section, we can use this Map.entry() Utility method to create an Immutable Map.Entry using given Key and value pairs. It is used as part of Map.ofEntries() method to create an Immutable Map as shown in the above example.

Map.entry() method API:-

static <K,V> Map.Entry<K,V> entry(K k, V v)

Map.entry() method Example:-

jshell> Map.Entry<Integer,String> immutableMapEntry1 = Map.entry(1,"one")immutableMapEntry1 ==> 1=onejshell> Map.Entry<Integer,String> immutableMapEntry2 = Map.entry(2,"two")immutableMapEntry2 ==> 2=twojshell> Map.Entry<Integer,String> immutableMapEntry3 = Map.entry(3,"three")immutableMapEntry3 ==> 3=three

Here we have created three Immutable Map.Entry objects. Using these Entry objects, we can create an Immutable Map as shown below:

jshell> Map<Integer,String> immutableMap = Map.ofEntries(immutableMapEntry1,   ...> immutableMapEntry2, immutableMapEntry3)immutableMap ==> {3=three, 2=two, 1=one}

Popular posts from this blog

Window function in PySpark with Joins example using 2 Dataframes (inner join)

Complex SQL: fetch the users who logged in consecutively 3 or more times (lead perfect example)

Credit Card Data Analysis using PySpark (how to use auto broadcast join after disabling it)