Collection Factory Methods in Java 9

Collection Factory Methods in Java 9

In this post, we will explore Collection Factory Methods in Java 9. Java 9 introduced a new Convenience Factory Methods for Collections.

 

Introduction

Creating a new unmodifiable list in Java (before Java 9) is not very clean. Creating a small immutable collection in Java involves following steps

  1. Create collection.
  2. Add objects to Collection (e.g. Map)
  3. Wrap it using unmodifiableXXX()  method provided under java.util.Collections class.

To create an unmodifiable map in Java8 

 

public class ImmutableCollection {

    public static void main(String[] args) {

        Set<String> set = new HashSet<String>();
        set.add("one");
        set.add("two");
        set.add("three");

        Set<String> immutableSet = Collections.unmodifiableSet(set);
    }
}

Above code is definitely not very clean and concise, another option to create unmodifiable set are

public class ImmutableMap {

    public static void main(String[] args) {
        
        Set<String> immutableSet = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("one", "two","three")));
    }
}

Above code is a little cleaner but have following issues

  1. We need to create List before creating Set (extra Overhead).

 

Double Brace Initialization

We have the option to use double brace initialization for creating unmodifiable collection (Set in our example)

public class ImmutableCollectionDoubleBrace {

    public static void main(String[] args) {

        Set<String> immutableSet = Collections.unmodifiableSet(new HashSet<>() {{
            add("one");
            add("two");
            add("three");
        }});
    }
}

Above option also has multiple issues

  1. It will create an extra class with each usage.
  2. It contains references to the enclosing instance.

 

Java8 Stream API

We can also use Java 8 Stream to create an unmodifiable collection.

public class ImmutableCollectionStream {

    public static void main(String[] args) {
        
        Set<String> unmodifiableSet= Collections.unmodifiableSet(Stream.of("one","two","three").collect(Collectors.toSet()));
        
    }
}

Java 8 Stream API also have an issue and not a very clean solution to create an unmodifiable collection, additionally stream API involve unnecessary object creation along with some extra calculations.

 

Unmodifiable Collections in Java 9

They introduce collection Factory Methods in Java 9 like Scala (not same :)). Static methods have been provided by Java 9 on List, Set and Map interfaces which can easily returned unmodifiable collections by calling of() method of the respective interface.

 

List

public class Java9ImmutableList {

    public static void main(String[] args) {

        List<String> immutableList= List.of("1","2","3");
    }

}

Set

public class Java9ImmutableSet {

    public static void main(String[] args) {

        Set<String> immutableMap = Set.of("one","two","three");
    }
}

 

Map

public class Java9ImmutableMap {

    public static void main(String[] args) {

        Map<String, Integer> immutableMap = Map.of("one",1, "two", 2);
    }
}

Please note that Map.of() works with key and value pairs up to 10 entries. Beyond that, we need to use in a var-args of Entry instances and use Map.ofEntries()

public static void useMapEntries(){

    Map<String, Integer> map = Map.ofEntries(
            Map.entry("one", 1),
            Map.entry("two", 2),
            Map.entry("three", 3)
    );
}

Since every var-args method implicitly creates an array and to avoid performance issue, Java language team included 12 overloaded implementations for factory method for each collection type.

static <E> Set<E> of() 
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) 
.....

 

Null Element in Collection

Both List and Set will not allow adding a null element, Map does not allow null either as a key or value. If you will try to add a null element, JDK will throw NullPointerException.

public class NPEExample {

    public static void main(String[] args) {

        List<String> immutableList = List.of("one", null);
    }
}

 

Output

Exception in thread "main" java.lang.NullPointerException
 at java.base/java.util.Objects.requireNonNull(Objects.java:221)
 at java.base/java.util.ImmutableCollections$List2.<init>(ImmutableCollections.java:185)
 at java.base/java.util.List.of(List.java:822)
 at java/com.umeshawasthi.java9.example.NPEExample.main(NPEExample.java:9)

Introducing Collection Factory Methods in Java 9 is one of the useful features and will be useful in day to day programming. I have covered the feature of Collection Factory method along with some internal details. It is not nearly as convenient as Scala but I believe It’s a welcome change in Java 9.

 

All the code of this article is available Over on Github. This is a Maven-based project.

References

JEP 269

Comments are closed.