Thursday, August 23, 2018

Java9 Features - Collection API Changes

In this tutorial, We are going to learn about the Java9 features - Collection API Improvements with examples.

Java9 Collection API Improvements

Java9 added minor API changes to java.util.List, java.util.Map, java.util.Set interfaces
Added new static factory method - of(collection) and returns unmodified collection - List, Set and Map in iteration order.
This method takes a list of parameters as inputs and return the unmodified collection of List, Set and Map respectively.

Please see for more information JEP 269Convenience Factory Methods for Collections.

Why Factory Methods for Collections introduced?

Before java9 version, we have many ways to create an Unmodified Collection for few data items

The below section contains various ways to create an Unmodified collection with examples. For this examples, using the list as a sample, the same process we can adapt to declare and define Set and Map.

Simple Unmodified Collection Creation
We will create an Unmodified List, Set or Map with few elements is tedious tasks and unnecessary objects get created, First Object you need to create a list, Next constructs objects/elements, assign them with local variable, add this element by calling add(In case of List) method put in case of Set and Map) many times, convert normal list to Unmodified list.
List<String> list = new ArrayList<>();  
list.add("one");            
list.add("two");
list = Collections.unmodifiableList(list);

Copy Constructor Unmodified Collection Create

This is another way of creating glist using Arrays.asList method to define String array, populate via ArrayList Constructor
List<String> stringList = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList("one", "two")));

Double Brace Unmodified Collection Create

In this example, using anonymous inner classes with instances created in double braces.
List<String> strList = Collections.unmodifiableList(new ArrayList<>() {{
add("one"); add("two"); add("three");
}});
Java8 Unmodified Collection Creation
Convert the array of strings to Stream using Stream.of() method and convert the steam to List using Collectors.toList() method.
List<String> strLists = Collections.unmodifiableList(
Stream.of("one", "two", "three").collect(Collectors.toList()));
With java9, We can simply unmodified collection creation. We will see in the following examples.

List and Set Syntax and signature

List and Set have both overloaded of() methods with zero to 10 arguments. Syntax and signature for List and Set are same.
static <E> List<E> of()
static <E> List<E> of(E e1)
static <E> List<E> of(E e1,E e2)
// ..... so on upto ten parameters
static <E> List<E> of(E... e) // variable arguments
static <E> Set<E> of()
static <E> Set<E> of(E e1)
static <E> Set<E> of(E e1,E e2)
// ..... so on upto ten parameters
static <E> Set<E> of(E... e) // variable arguments

Map Syntax and Signature

The map has also zero to 10 arguments static method.
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3)
 
Like List and Set, Map also has a version of variable arguments method
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)

List.of() Factory static method example

It is simple to create a list and code is short. It takes three elements as input and return list of size 3. As this method is overloaded with 10 arguments, you can supply with up to 10 elements. If more are required to insert, You can use variable argument version of a method.

List<String> strList = List.of("one", "two", "three","four");

Set.of() factory static method example

Set.of method takes three parameters as input and return an unmodified collection.
Set<String> stringSet = Set.of("set1", "set2", "set3");
This method of() would not allow duplicate elements, duplicates elements throws java.lang.IllegalArgumentException: duplicate element.
Set.of("one", "two", "three", "one");
the output of the above code is
 
Exception in thread "main" java.lang.IllegalArgumentException: duplicate element: one
 at java.base/java.util.ImmutableCollections$SetN.(ImmutableCollections.java:463)
 at java.base/java.util.Set.of(Set.java:521)
 at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:41)

Map.of() Factory static method example

This interface has two methods of and ofEntries for creating the collection.

versions  one for creating map up
Map<Integer, String> mapDemo = Map.of(1, "one", 2, "two", 3, "three");
 // variable arguments example
Map<String, String> map = Map.ofEntries(
  new AbstractMap.SimpleEntry<>("key1", "value1"),
  new AbstractMap.SimpleEntry<>("key2", "value2"),
  new AbstractMap.SimpleEntry<>("key3", "value3"));
Duplicate keys
Passing Duplicate keys to Map with of() throws java.lang.IllegalArgumentException: duplicate key exception
Map.of("one", "value1", "one", "value2");
and output is
Exception in thread "main" java.lang.IllegalArgumentException: duplicate key: one
at java.base/java.util.ImmutableCollections$MapN.(ImmutableCollections.java:681)
at java.base/java.util.Map.of(Map.java:1327)
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:41)
unmodified collection - java.lang.UnsupportedOperationException Exception
Set<String> strSet = Set.of("one", "two");
strSet.add("three");
Output is
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)
at java.base/java.util.ImmutableCollections$AbstractImmutableSet.add(ImmutableCollections.java:281)
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:39)

Unmodified collection Null values not accepted

Set.of("one", "two", null);
ist.of("one", "two", null);
Output is
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at java.base/java.util.ImmutableCollections$ListN.(ImmutableCollections.java:234)
at java.base/java.util.List.of(List.java:842)
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:39)
if Null values passed as either key or value of Map, throws java.lang.UnsupportedOperationException
Set<String> strSet = Set.of("one", "two");
strSet.add("three");
Output is
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)
at java.base/java.util.ImmutableCollections$AbstractImmutableSet.add(ImmutableCollections.java:281)
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:39)

Inheritance

These static methods Can not be overridden. We can not use them using subclass implementation or an instance type. They can be called using interface name only.

Collection Factory static method feature.

  • It returns Unmodified Collection
  • if the elements are serialized, returned collection is also serialized
  • No Null key and values are not allowed in Map
  • Null values are not allowed in List and Set
  • These collections are immutable, Any mutable methods(adding/modifying/deleting elements from a collection) throws UnsupportedOperationException.
  • Duplicates are not allowed and Ordering is unordered in Set
  • The list allows duplicates but the returned collection is based on original insertion order

Related article


EmoticonEmoticon