Convert a Stream to a Map in Java
This post will discuss how to convert a stream to a map in Java.
1. Converting Stream of String[]
We can use the Java 8 Stream to construct maps by obtaining stream from static factory methods like Stream.of() or Arrays.stream() and accumulating the stream elements into a new map using collectors.
We know that a stream of String[] is essentially a sequence of items, not a sequence of key/value pairs. To extract a map out of it, we can use the Collectors.toMap() method, where we provide proper mapping functions to specify how to extract keys and values from stream elements.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { // Method to get stream of `String[]` private static Stream<String[]> getMapStream() { return Stream.of(new String[][] { {"CAR", "Audi"}, {"BIKE", "Harley Davidson"} }); } // Program to convert stream to a map in Java 8 and above public static void main(String[] args) { // get a stream of `String[]` Stream<String[]> stream = getMapStream(); // construct a new map from the stream Map<String, String> vehicle = stream.collect(Collectors.toMap(e -> e[0], e -> e[1])); System.out.println(vehicle); } } |
Output:
{CAR=Audi, BIKE=Harley Davidson}
To initialize a map with different types for key and value, we can do:
|
1 2 3 |
Map<String, Integer> map = Stream.of(new Object[][]{{"A", 65}, {"B", 66}}) .collect(Collectors.toMap(e -> (String)e[0], e -> (Integer)e[1])); |
We could also adapt a collector to perform an additional finishing transformation. For example, we could adapt the toMap() collector to always produce an immutable map with:
|
1 2 3 |
Map<String, String> immutableMap = getMapStream() .collect(Collectors.collectingAndThen(Collectors.toMap(e -> e[0], e -> e[1]), Collections::<String, String>unmodifiableMap)); |
2. Converting stream of Map.Entry to Map
Method references in Java 8 and above made it very easy to construct maps from a stream of Map.Entry, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { // Method to get stream of map mappings private static Stream<Map.Entry<String, String>> getMapStream() { Map<String, String> vehicle = new HashMap<>(); vehicle.put("CAR", "Audi"); vehicle.put("BIKE", "Harley Davidson"); return vehicle.entrySet().stream(); } // Program to convert stream to a map in Java 8 and above public static void main(String[] args) { // get map stream Stream<Map.Entry<String, String>> stream = getMapStream(); // construct a new map from the stream Map<String, String> map = stream.collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue)); System.out.println(map); } } |
Output:
{CAR=Audi, BIKE=Harley Davidson}
As seen before, to get an immutable map, we can do:
|
1 2 3 4 |
Map<String, String> immutableMap = getMapStream().collect(Collectors.collectingAndThen( Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue), Collections::<String, String>unmodifiableMap)); |
We can also use lambda expressions instead of method references.
|
1 2 3 |
Map<String, String> map = getMapStream().collect(Collectors.toMap(x -> x.getName(), x -> x.getCode())); |
Collectors class provides several overloaded versions of the toMap() method:
1. For any duplicate keys present on the map, to avoid IllegalStateException, we can provide a merge function, which is used to resolve collisions between values associated with the same key or create a multimap by using Collectors.groupingBy() as demonstrated here.
|
1 2 3 4 |
Map<String, String> map = getMapStream().collect(Collectors.toMap(x -> x.getName(), x -> x.getCode(), (oldValue, newValue) -> newValue)); |
2. We can also specify the type of the map instance to be returned in another version of the
toMap() method, as shown below:
|
1 2 3 4 5 |
Map<String, String> map = getMapStream().collect(Collectors.toMap(x -> x.getName(), x -> x.getCode(), (oldValue, newValue) -> newValue, TreeMap::new)); |
3. Converting stream of AbstractMap.SimpleEntry
Another approach that can easily accommodate different types for key and value involves creating a stream of map entries. There are two implementations of the Map.Entry interface:
1. Using AbstractMap.SimpleEntry<K,V>:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import java.util.AbstractMap; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { // Method to get stream of map mappings private static Stream<AbstractMap.SimpleEntry<String, String>> getMapStream() { return Stream.of( new AbstractMap.SimpleEntry<>("USA", "Washington DC"), new AbstractMap.SimpleEntry<>("UK", "London")); } // Program to convert stream to a map in Java 8 and above public static void main(String[] args) { // construct a new map from the stream Map<String, String> capital = getMapStream() .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); System.out.println(capital); } } |
Output:
{USA=Washington DC, UK=London}
2. Using AbstractMap.SimpleImmutableEntry<K,V>:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import java.util.AbstractMap; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { // Method to get stream of map mappings private static Stream<AbstractMap.SimpleImmutableEntry<String, String>> getMapStream() { return Stream.of( new AbstractMap.SimpleImmutableEntry<>("USA", "Washington DC"), new AbstractMap.SimpleImmutableEntry<>("UK", "London")); } // Program to convert stream to a map in Java 8 and above public static void main(String[] args) { // construct a new map from the stream Map<String, String> capital = getMapStream().collect(Collectors.toMap( AbstractMap.SimpleImmutableEntry::getKey, AbstractMap.SimpleImmutableEntry::getValue)); System.out.println(capital); } } |
Output:
{USA=Washington DC, UK=London}
That’s all about converting Stream to a Map in Java.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)