Java 8 Stream – From List to Map

An example to convert a List<?> to a Map<K,V> using Java 8 Stream.

Java 8 – Collectors.toMap()

Let’s define a Pojo class:

In the first example, we convert a List<Person> in a Map<String, Person> that has email as key and the object itself as value.

The output will be:

Or using lambda:

Output:

Let’s break this out

First of all, we create a Stream of Person from the List<Person> defined.

Then we collect this stream in a Map. Java 8 helps us to define the needed Collector by providing us the method: Collectors.toMap().

Collectors.toMap() takes two functions – one for mapping the key and one for the value – and returns a Collector that accumulates elements into a Map.

Since we are working with Stream of Person – our input it’s an object Person.

We have chosen the email as key, so that is a function that given the input – Person – returns its email:

and then the object itself as value, so it’s just an identity function:

These are the parameters for toMap.

Another example

Given a List<Person> we want to create a Map<String, Integer> that contains the name as key and the age as value.

We just need to change the two parameters of the Collectors.toMap, by specifying:

So the code will be:

Output:

If you are a good observer you may have noticed that the order hasn’t been respected. That’s because the default implementation used by toMap is the HashMap that does not guarantee the order of the map.

 

Java 8 – Collectors.toMap with a LinkedHashMap

 

If we want to preserve the order we should use a LinkedHashMap instead of the HashMap.

Let’s try the previous example by passing a LinkedHashMap to Collectors.toMap()

Output:

We are using the definition of toMap that takes four parameters:

  • keyMapper – a mapping function to produce keys
  • valueMapper – a mapping function to produce values
  • mergeFunction – a merge function used to resolve collisions between values associated with the same key
  • mapSupplier – a function which returns a new, empty Map into which the results will be inserted

We’ve already discussed the first two parameters.

In case of a collision we just want to throw an exception, so as third parameter we define that. In the example, we used the same implementation of the static method throwingMerger defined in the java.util.stream.Collectors class.

The fourth parameter it’s the one in which we define a function that returns our LinkedHashMap.

Java 8 – Convert List to String comma separated

Convert a List<String> in a String with all the values of the List comma separated in Java 8 is really straightforward. Let’s have a look how to do that.

In Java 8:

We simply can write String.join(..), pass a delimiter and an Iterable and the new StringJoiner will do the rest:

In case we are working with a stream we can write as follow and still have the same result:

Note: you can statically import java.util.stream.Collectors.joining if you prefer just typing “joining“.

In Java 7:

For the old times’ sake, let’s have a look at Java 7 implementation.

As you can see it’s much more verbose and easier to make mistakes like forgetting to remove the last comma. You can implement this in several ways – for example by moving the logic that removes the last comma inside the for-loop – but none will be so explicative and immediate to understand as the declarative solution expressed in Java 8.

The focus should be on what you want to do – joining a List of String – not on how.

 

Java 8: Manipulate String before joining

Before joining you can manipulate your String as you prefer by using map() or cutting some String out by using filter().  I’ll cover those topics in further articles. Meanwhile, this a straightforward example on how to transform the whole String in upper-case before joining them.

Java 8: From List to upper-case String comma separated

If you want to find out more about stream, I strongly suggest this cool video of Venkat Subramaniam.

Let’s play

The best way to learn it’s playing! Copy this class with all the implementations discussed and play with that. There is already a small test for each of them 🙂