Tuesday, September 26, 2017

Java 9: Factory Methods to initialize Immutable Collections

Java 9 introduces convenient factory methods to create immutable List, Map, and Set collections. In this post, I will show how to use the new factory methods to

Java 8 Immutable Collections

Prior to Java 9, to create immutable collections, you would something like below
List<String> list8 = new ArrayList<String>();
list8.add("YHOO");
list8.add("AAPL");
list8.add("GOOG");
list8.add("MSFT");

List<String> immutableList8 = Collections.unmodifiableList(list8);
//immutableList8.add("ORCL");// Will throw java.lang.UnsupportedOperationException
immutableList8.forEach(System.out::println);
This example shows only an implementation for List (Although Arrays.asList(..) would have done as well), and Set and Map would look something similar too.

Initialize Immutable List in Java 9

In Java 9, java.util.List provides multiple methods to initialize immutable lists, shown below
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)
static <E> List<E> of(E... elements) // Var-args variation
Following is an example of how to use this to create a List
List<String> immutableList = List.of("YHOO", "AAPL", "GOOG", "MSFT");
// immutableList.add("ORCL"); // Will throw java.lang.UnsupportedOperationException
immutableList.for/ESystem.out::println);

Initialize Immutable Set in Java 9

Similar to List, you have the same type of methods for java.util.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)
static <E> Set<E> of(E... elements) // Var-args variation
Following example demonstrates how to use this to create a Set
Set<String> immutableSet = Set.of("YHOO", "AAPL", "GOOG", "MSystem.out::println);

Initialize Immutable Map in Java 9

When it comes to java.util.Map the simple methods support upto 10 <key,value> pairs.
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)
Here is a simple way to initialize an Immutable Map
Map<String, String> immutableMap = Map.of("YHOO", "Yahoo", "AAPL", "Apple", "GOOG", "Alphabet", "MSFT", "Microsoft");
immutableMap.forEach((key, value) -> System.out.println(key + " : " + value));
Beyond that the var-args, that variation takes a variable number of arguments of "java.util.Map.entry"
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
Here is an example of how to use the varags variation to initialize an immutable Map
Map<String, String> immutableMap2 = Map.ofEntries(Map.entry("YHOO", "Yahoo"), Map.entry("AAPL", "Apple"), Map.entry("GOOG", "Alphabet"), Map.entry("MSFT", "Microsoft"));
immutableMap2.forEach((key, value) -> System.out.println(key + " : " + value));

The Full Code to directly run these examples

package com.aoj.java9.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Immutables {

  public static void main(String[] args) {
    List<String> list8 = new ArrayList<String>();
    list8.add("YHOO");
    list8.add("AAPL");
    list8.add("GOOG");
    list8.add("MSFT");
  
    List<String> immutableList8 = Collections.unmodifiableList(list8);
    //immutableList8.add("ORCL");// Will throw java.lang.UnsupportedOperationException
    immutableList8.forEach(System.out::println);
    
    List<String> immutableList = List.of("YHOO", "AAPL", "GOOG", "MSFT");
    // immutableList.add("ORCL"); // Will throw java.lang.UnsupportedOperationException
    immutableList.forEach(System.out::println);

    Map<String, String> immutableMap = Map.of("YHOO", "Yahoo", "AAPL", "Apple", "GOOG", "Alphabet", "MSFT", "Microsoft");
    immutableMap.forEach((key, value) -> System.out.println(key + " : " + value));

    Map<String, String> immutableMap2 = Map.ofEntries(Map.entry("YHOO", "Yahoo"), Map.entry("AAPL", "Apple"), Map.entry("GOOG", "Alphabet"), Map.entry("MSFT", "Microsoft"));
    immutableMap2.forEach((key, value) -> System.out.println(key + " : " + value));
    
    Set<String> immutableSet = Set.of("YHOO", "AAPL", "GOOG", "MSFT");
    immutableSet.forEach(System.out::println);
  }
}

No comments:

Post a Comment

Popular Posts