Convert List to Map in Java
This post will discuss how to convert a list to a map in Java.
Consider the following Color class, which contains two private fields – name and code. They represent the color name and its corresponding HTML color code, respectively.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Color { private String name; private String code; public Color(String name, String code) { this.name = name; this.code = code; } @Override public String toString() { return name + "=" + code; } // getters and setters } |
In the following example, we’ll see how we can construct a map from a list of Color objects.
|
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; class Color { private String name; private String code; public Color(String name, String code) { this.name = name; this.code = code; } @Override public String toString() { return name + "=" + code; } // getters and setters public String getCode() { return code; } public String getName() { return name; } } class Main { // program to convert a list to a map in Java public static void main(String[] args) { // input list of `Color` objects List<Color> colors = new ArrayList<>(); colors.add(new Color("RED", "#FF0000")); colors.add(new Color("BLUE", "#0000FF")); colors.add(new Color("GREEN", "#008000")); Map<String, String> map = new HashMap<>(); // construct key-value pairs from `name` and `code` fields of `Color` class for (Color ob: colors) { map.put(ob.getName(), ob.getCode()); } System.out.println("List : " + colors); System.out.println("Map : " + map); } } |
Output:
List : [RED=#FF0000, BLUE=#0000FF, GREEN=#008000]
Map : {RED=#FF0000, BLUE=#0000FF, GREEN=#008000}
This can be easily done using Java 8 Stream:
|
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Color { private String name; private String code; public Color(String name, String code) { this.name = name; this.code = code; } @Override public String toString() { return name + "=" + code; } // getters and setters public String getCode() { return code; } public String getName() { return name; } } class Main { public static void main(String[] args) { // input list of `Color` objects List<Color> colors = new ArrayList<>(); colors.add(new Color("RED", "#FF0000")); colors.add(new Color("BLUE", "#0000FF")); colors.add(new Color("GREEN", "#008000")); // construct key-value pairs from `name` and `code` fields of `Color` class Map<String, String> map = colors.stream() .collect(Collectors.toMap(Color::getName, Color::getCode)); System.out.println("List : " + colors); System.out.println("Map : " + map); } } |
Output:
List : [RED=#FF0000, BLUE=#0000FF, GREEN=#008000]
Map : {RED=#FF0000, BLUE=#0000FF, GREEN=#008000}
We can also use lambda expressions instead of method references.
|
1 2 |
colors.stream().collect(Collectors.toMap(x -> x.getName(), x -> x.getCode())); |
Collectors class provides several overloaded versions of the toMap() method:
1. If duplicate keys are present on the map, an IllegalStateException is thrown when the collection operation is performed.
We can provide a merge method used to resolve collisions between values associated with the same key (normally, either the old value or new value in the stream takes precedence).
|
1 2 3 |
colors.stream().collect(Collectors.toMap(x -> x.getName(), x -> x.getCode(), (oldValue, newValue) -> newValue)); |
2. The default implementation of toMap() doesn’t specify the Type of the map object returned. We can supply the Type of map in another overloaded version of the toMap() method, as shown below:
|
1 2 3 4 |
colors.stream().collect(Collectors.toMap(x -> x.getName(), x -> x.getCode(), (oldValue, newValue) -> newValue, TreeMap::new)); |
Here’s is one more example where we have a list of specific ASCII characters, and we’ll construct a map out of it that represents the ASCII character table.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; class Main { public static void main(String[] args) { // list of ASCII characters List<String> chars = Arrays.asList("A", "B", "C", "D"); // Map to represent the ASCII character table Map<String, Integer> asciiMap = null; asciiMap = chars.stream().collect(Collectors.toMap(Function.identity(), String::hashCode)); System.out.println(asciiMap); } } |
Output:
{A=65, B=66, C=67, D=68}
This is equivalent to:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; class Main { public static void main(String[] args) { // list of ASCII characters List<String> chars = Arrays.asList("A", "B", "C", "D"); // Map to represent the ASCII character table Map<String, Integer> asciiMap = new HashMap<>(); for (String s : chars) { if (asciiMap.put(s, s.hashCode()) != null) { throw new IllegalStateException("Duplicate key"); } } System.out.println(asciiMap); } } |
Output:
{A=65, B=66, C=67, D=68}
Creating MultiMap
We can use Collectors.groupingBy() to perform the equivalent of a database cascaded “group by” operation on input elements, 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 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Vehicle { private String type; private String company; public Vehicle(String type, String company) { this.type = type; this.company = company; } public String getType() { return type; } public String getCompany() { return company; } } class Main { public static void main(String[] args) { // list of vehicles List<Vehicle> vehicles = Arrays.asList( new Vehicle("Bike", "Harley Davidson"), new Vehicle("Bike", "Triumph"), new Vehicle("Car", "Mercedes"), new Vehicle("Car", "Audi"), new Vehicle("Car", "BMW")); Map<String, List<String>> multimap = vehicles.stream() .collect(Collectors.groupingBy(Vehicle::getType, Collectors.mapping(Vehicle::getCompany, Collectors.toList()))); System.out.println(multimap); } } |
Output:
{Car=[Mercedes, Audi, BMW], Bike=[Harley Davidson, Triumph]}
Here’s an equivalent version without using the Stream API.
|
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 32 33 34 35 36 37 38 39 40 41 42 43 |
import java.util.*; class Vehicle { private String type; private String company; public Vehicle(String type, String company) { this.type = type; this.company = company; } public String getType() { return type; } public String getCompany() { return company; } } class Main { public static void main(String[] args) { // list of vehicles List<Vehicle> vehicles = Arrays.asList( new Vehicle("Bike", "Harley Davidson"), new Vehicle("Bike", "Triumph"), new Vehicle("Car", "Mercedes"), new Vehicle("Car", "Audi"), new Vehicle("Car", "BMW")); Map<String, List<String>> multimap = new HashMap<>(); for (Vehicle vehicle : vehicles) { multimap.computeIfAbsent(vehicle.getType(), k -> new ArrayList<>()) .add(vehicle.getCompany()); } System.out.println(multimap); } } |
Output:
{Car=[Mercedes, Audi, BMW], Bike=[Harley Davidson, Triumph]}
That’s all about converting List to 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 :)