Wednesday, April 19, 2023

How to create Immutable List, Set, and Map in Java? List.of(), Set.of() and Map.of() Examples

Hello guys, this is my first article in Java 9 features on this blog, and today you'll learn about my favorite feature "factory methods for collection", which is introduced as part of JEP 269. The JEP stands for the JDK enhancement proposal. If you have worked in Groovy or Kotlin then you know that how easy is to create the list with elements using collection literals e.g. to create a list of 1, 2, 3 you can simply write val items = listOf(1, 2, 3). Unfortunately, Java doesn't support that yet but things have been improved with the factory methods for collection in JDK 9 and it's almost like that. JDK has added static factory methods like of() on to basic Collection interfaces which you can use to create a list of items.

Even though the Project Jigsaw or Java Module systems is the main highlight of the Java 9 release, there are several other useful features that are more helpful from a development point of view e.g. process API enchantment, Stream API enhancements, and some useful methods on Optional class, but the API change which I liked most is the factory methods for Collection.

It allows you to create a list, set, and a map of values in just one line, just like you can do in Kotlin, Scala, or Groovy:

List<String> list = List.of("Java", "Kotlin", "Groovy");

But, the only catch is that you can create an unmodifiable or immutable List, Set, or Map.

The List, Set or Map returned by the of() static factory method are structurally immutable, which means you cannot add, remove, or change elements once added.

Calling any mutator method will always cause UnsupportedOperationException to be thrown. However, if the contained elements are themselves mutable, this may cause the Collection to behave inconsistently or its contents to appear to change. If you are not familiar with the Java Collection framework then The Complete Java MasterClass course on Udemy is a good starting point. It not only covers the Collections but also other essential Java topics like threads, networking, and IO.




How to create Immutable List, Set, and Map in Java 8

This is the same as the unmodifiable list you create in JDK 6 or 7 as shown below:
List<String> listOfString = new List<>();
listOfString.add("Java");
listOfString.add("Kotlin");
listOfString.add("Groovy");
listOfString.add("Scala");
listOfString = Collections.unmodifiableList(listOfString);

The list returned by the unmodifiableList() method also doesn't support add, remove, or set operation and throws UnsupportedOperationException if you call them.

The only difference between the two codes is that earlier it required more than 6 lines of code to create an immutable Collection like an immutable List, Set, or Map but now you can do that in just one line.

There are also several overloaded versions of List.of() is available on the List interface e.g. to allow you to create an immutable list of 1 to 10 elements and a variable argument method that allows you to create the list of any number of elements.

Same is true for Set.of() and Map.of() method as well. Here is the example of creating an immutable Set in Java 9:
Set<Integer> primes = Set.of(2,3,5,7);
You can see that you can create an immutable Set in just one line. Similarly, to create an immutable Map, JDK 9 provides two methods Map.of(K k1, V v1) and Map.ofEntries() by using these two you can create a Map of immutable entries e.g.

Java 9 Example - Factory Methods for Collection - Creating Unmodifiable List, Set, and Map

This method is overloaded to create a map of up to 10 key-value pairs but if you need a bigger map with more mapping then you should use Map.ofEntries() method.

Btw, do you know how this feature is implemented? and why it wasn't available before? If you look at JDK 9 code or Javadoc then you will find that this feature is implemented by adding static factory method on key interfaces of Java Collection framework like List, Set, and Map.

This wasn't possible until JDK 8 because adding a method on the interface means breaking all its clients and static methods were not allowed on the interface. Things changed on Java 8 with the introduction of default and static methods on the interface which pave the way for evaluating the JDK API.

I hope more similar enchantment will come in the future which makes using JDK API even easier. If you are not familiar with JDK 8 changes yet, the What's New in Java 8 course on Pluralsight is a good starting point.


Also, the rules that apply to the use of the different collections also apply (as you would expect) when using these factory methods. So, you cannot pass a duplicate element when you create a Set because Set doesn't allow duplicate.

Similarly, you cannot pass duplicate keys when you create a Map because Map doesn't allow duplicate keys. If you do then IllegalArgumentException will be thrown

Also, you can't pass a null value to the collection factory method, if you do, be ready for the kind of Java exception, the NullPointerException.


That's all about how to create an immutable list, set, and map in Java 9. The static method on collections has really made using Java collection API easier and at least it's now similar to what Kotlin or Groovy offer. JDK 9 is full of such useful features and stay tuned for more of such articles on this blog. If you can't wait, check out What's New in Java 9 - Modules and more, which provides a nice overview of all JDK 9 features.


Other Java and Programming Articles you may like

Thanks for reading this article so far. If you like this Java 9 feature then please share it with your friends and colleagues. If you have any questions for feedback then please drop a note.

P. S. - If you new to the Java world and looking for a comprehensive course to start your journey, there is no better course than The Complete Java Masterclass on Udemy. It is most up-to-date and covers everything a Java programmer should know.

1 comment :

DuttUtpal said...

"list is abstract cannot be instantiated"

I get above error when i run the code in Netbeans IDE. Am I not using it correctly?

Post a Comment