Java 8 Streams: Convert List into Map


Introduction

In this post we’ll see how to use Java Streams introduced in Java 8 to obtain a Map from a List.

Maps are data structures composed of a collection of key-value elements such that a key is unique within the collection. This allows us to perform searches to find an element with a given key really quickly, without the need to iterate through the full collection.

It’s a really common situation that when we have to solve a problem where the start point is a list of elements, we need to convert this list to a map so that we can optimize the performance of the algorithm for the solution. It is at these times when Java 8 Streams allow us to perform this conversion in a simple and elegant way.

In this post we’ll see how to convert a list of Github repositories into a map. We start with the class GithubRepo:

List to Map with no duplicate keys

If we are really sure that the List we want to convert into a Map contains no duplicate elements, we can use the following code:

The first step is to convert the list into a Stream and then, without any transformation, collect the results using one of the default Java 8  Collectors.

For the Map key we are going to use the name of the repository in this case we are using the code GithubRepo::getName which is the recommended equivalent for the expression gr -> gr.getName(). As the Map value we want to use the same element from the list, for this purpose Java offers out of the box Function.identity() which is the recommended equivalent for the expression gr -> gr.

As already stated, one of the requirements for this Collector is that there are no duplicate keys within the initial list. In case a duplicate key is received, an IllegalStateException will be thrown as you can see in this test listToMap_duplicatesList_shouldThrowException.

List to Map with duplicate keys

If we are not sure or we simply don’t know if the original list contains duplicities we’ll use another Collector that can manage merging for these duplicities. For this sake, the method we used earlier admits a third parameter as a lambda expression that will be in charge of merging the elements for a given duplicate key.

The example shows an anonymous function as the third parameter for the toMap collector. This function has 2 initial parameters ghrPrevious and ghrNew and must return a single element of the same type. In this case we are returning the newer element (ghrNew) but you could return the previous or a transformation of either of them or a new one.

List to Map keeping key ordering

Collectors.toMap admits a fourth parameter to specify the constructor of the Map that the method returns.

In this case we want to obtain an instance of TreeMap  which implements the SortedMap interface. This Map is sorted by the natural ordering of its keys or by the comparator provided at the constructor argument.

In the previous example the map will sorted alphabetically by the order of its keys. In the next example  the map will be sorted by reverse order of its keys as it’s using Comparator.reverseOrder() as the TreeMap constructor argument:

Conclusion

This post shows how to convert in a simple and elegant way a List data structure to a Map data structure using Java 8 streams and the method Collectors.toMap.

You can find the full source code for this article at GitHub.

Java 8 Streams

Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+Pin on PinterestEmail this to someone

Leave a comment

Your email address will not be published. Required fields are marked *