Got a business need to take a List of Java objects and convert it into a Map?

No worries. I'm here to help.

I'll show you a solution that works great assuming you're using Java 8 or later. But by the time this blog post goes to press, I'm pretty sure everybody is using Java 8 or later.

So let's get this ball rolling.

The Reqs

Let's say you're developing a CRM application and you've got a List of SalesOwner objects. 

And you need to convert that List to a Map.

Moreover, you want the ID of each SalesOwner object to be the key in the Map. The value will be the whole object itself.

So let's get some pretend data going to test out our solution:

SalesOwner so1 = new SalesOwner();
so1.setId("1");
so1.setUsername("bozo");

SalesOwner so2 = new SalesOwner();
so2.setId("2");
so2.setUsername("gonzo");

SalesOwner so3 = new SalesOwner();
so3.setId("3");
so3.setUsername("tweedle");

List<SalesOwner> salesOwners = List.of(so1, so2, so3);

Nothing overly fancy there. 

The code just instantiates three (3) SalesOwner objects with IDs and usernames. Then it stores them in a List.

Now it's time to convert that List to a Map.

A Conversation About Conversion

I mentioned above that you need Java 8 or later to make this conversion happen. And the reason you need Java 8 or later is because I'm going to show you a solution that uses a Stream.

In Java, a Stream is a sequence of objects that offers a variety of methods you can pipeline to create a new sequence of objects or a single object.

Here's how you can use it to convert that List to a Map:

Map<String, SalesOwner> map = salesOwners
                                .stream()
                                .collect(Collectors.toMap(SalesOwner::getId, Function.identity()));

The code above gets the Stream object with the appropriately named stream() method.

Then, it invokes just a single terminal operation on the stream: collect().

The collect() method transforms the stream into some other type of object, such as a List or a Map.

Here, the collect() method accepts a single parameter: it's a type of Collector. And that Collector is instantiated by the Collectors.toMap() method.

As you can probably guess, Collectors.toMap() returns a Map.

But it needs to know how to create that Map. Hence the two parameters inside the toMap() method.

The first parameter identifies the key in the Map while the second parameter identifies the value.

Both parameters are functions. That's why you're seeing some notation and references that you might not see all too often.

The first parameter is a method reference: SalesOwner::getId. That makes sense because method references are functions.

As you can probably tell by looking at that reference, it tells the code to use the sales owner ID as the key.

The second parameter, Function.identity(), is a convenient way of saying "the whole object." In other words, the entire SalesOwner object becomes the value the in the Map.

And that's it. Run that code and evaluate the contents of the resulting Map and you'll see it works beautifully.

Wrapping It Up

Pretty easy, huh?

Now it's your turn. Take what you've learned here and put it in an application that you're developing. Then, use the Map object as you see fit.

Have fun!

Photo by Francesco Paggiaro from Pexels