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:
1/** ... **/
2public class GithubRepo {
3 private String name;
4 @JsonProperty("full_name")
5 private String fullName;
6 private String description;
7 private Boolean fork;
8 @JsonIgnore
9 private Integer localVersion;
10 /** ... **/
11}
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:
1repos.stream().collect(Collectors.toMap(GithubRepo::getName, Function.identity()));
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 Collector
s.
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.
1repos.stream().collect(Collectors.toMap(GithubRepo::getName, Function.identity(),
2 (ghrPrevious, ghrNew) -> ghrNew));
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.
1repos.stream().collect(Collectors.toMap(GithubRepo::getName, Function.identity(),
2 (ghrPrevious, ghrNew) -> ghrNew, TreeMap::new));
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:
1repos.stream().collect(Collectors.toMap(GithubRepo::getName, Function.identity(),
2 (ghrPrevious, ghrNew) -> ghrNew,
3 () -> new TreeMap(Comparator.reverseOrder())));
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.