Introduction
In Java 8, converting a List to a Map is a common task when you need to map specific keys to corresponding values. The Stream API provides a straightforward and functional way to perform this conversion using Collectors.toMap(). This method requires you to define how the keys and values should be extracted from the elements in the list.
In this guide, we will learn how to convert a list to a map using Java 8’s Stream API.
Solution Steps
- Define the List: Create a list of elements (e.g., custom objects) that you want to convert to a map.
- Use Stream and
Collectors.toMap(): Convert the list to a stream and applyCollectors.toMap()to define the key-value mapping. - Handle Duplicate Keys (if needed): Optionally handle cases where duplicate keys might exist by providing a merge function.
- Display the Result: Print or use the resulting map.
Java Program
Example 1: Convert a List of Strings to a Map
In this example, we convert a list of strings to a map where the key is the string and the value is the length of the string.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ListToMapExample {
public static void main(String[] args) {
// Step 1: Define the List of strings
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange", "Mango");
// Step 2: Convert the List to a Map (key: string, value: length of string)
Map<String, Integer> fruitMap = fruits.stream()
.collect(Collectors.toMap(
fruit -> fruit, // Key: the fruit itself
fruit -> fruit.length() // Value: the length of the fruit string
));
// Step 3: Display the Map
System.out.println(fruitMap); // Output: {Apple=5, Banana=6, Orange=6, Mango=5}
}
}
Output
{Apple=5, Banana=6, Orange=6, Mango=5}
Explanation
Step 1: Define the List
We define a list of strings:
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange", "Mango");
Step 2: Convert the List to a Map
We use Collectors.toMap() to convert the list into a map. The key is the fruit name, and the value is the length of the fruit name:
Map<String, Integer> fruitMap = fruits.stream()
.collect(Collectors.toMap(
fruit -> fruit, // Key: the fruit itself
fruit -> fruit.length() // Value: the length of the fruit string
));
Step 3: Display the Map
We print the resulting map:
System.out.println(fruitMap);
Example 2: Convert a List of Custom Objects to a Map
In this example, we convert a list of Employee objects to a map where the key is the employee’s name, and the value is the employee object itself.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ListToMapCustomObjects {
public static void main(String[] args) {
// Step 1: Define a list of Employee objects
List<Employee> employees = Arrays.asList(
new Employee("Ravi", 30),
new Employee("Amit", 25),
new Employee("Pooja", 35)
);
// Step 2: Convert the List to a Map (key: employee name, value: employee object)
Map<String, Employee> employeeMap = employees.stream()
.collect(Collectors.toMap(
Employee::getName, // Key: employee name
employee -> employee // Value: employee object
));
// Step 3: Display the Map
employeeMap.forEach((name, employee) ->
System.out.println("Name: " + name + ", Employee: " + employee));
}
}
// Employee class
class Employee {
private String name;
private int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name + ": " + age;
}
}
Output
Name: Ravi, Employee: Ravi: 30
Name: Amit, Employee: Amit: 25
Name: Pooja, Employee: Pooja: 35
Explanation
Step 1: Define the List of Custom Objects
We define a list of Employee objects:
List<Employee> employees = Arrays.asList(
new Employee("Ravi", 30),
new Employee("Amit", 25),
new Employee("Pooja", 35)
);
Step 2: Convert the List to a Map
We use Collectors.toMap() to convert the list into a map. The key is the employee’s name, and the value is the employee object itself:
Map<String, Employee> employeeMap = employees.stream()
.collect(Collectors.toMap(
Employee::getName, // Key: employee name
employee -> employee // Value: employee object
));
Step 3: Display the Map
We print each entry in the map:
employeeMap.forEach((name, employee) ->
System.out.println("Name: " + name + ", Employee: " + employee));
Example 3: Handling Duplicate Keys in toMap()
If your list contains duplicate keys, you can provide a merge function to handle collisions. In this example, we merge employees by keeping the employee with the higher age if they share the same name.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ListToMapWithDuplicates {
public static void main(String[] args) {
// Step 1: Define a list of Employee objects with duplicate names
List<Employee> employees = Arrays.asList(
new Employee("Ravi", 30),
new Employee("Ravi", 35), // Duplicate name with higher age
new Employee("Amit", 25)
);
// Step 2: Convert the List to a Map, resolving duplicate keys by keeping the older employee
Map<String, Employee> employeeMap = employees.stream()
.collect(Collectors.toMap(
Employee::getName, // Key: employee name
employee -> employee, // Value: employee object
(e1, e2) -> e1.getAge() > e2.getAge() ? e1 : e2 // Merge function
));
// Step 3: Display the Map
employeeMap.forEach((name, employee) ->
System.out.println("Name: " + name + ", Employee: " + employee));
}
}
Output
Name: Ravi, Employee: Ravi: 35
Name: Amit, Employee: Amit: 25
Explanation
Step 1: Define the List of Custom Objects with Duplicate Names
We define a list of employees where two employees share the same name, but one has a higher age:
List<Employee> employees = Arrays.asList(
new Employee("Ravi", 30),
new Employee("Ravi", 35), // Duplicate name
new Employee("Amit", 25)
);
Step 2: Use a Merge Function to Handle Duplicates
We use a merge function in toMap() to resolve duplicate keys. The merge function compares the age of the employees with the same name and keeps the one with the higher age:
.collect(Collectors.toMap(
Employee::getName,
employee -> employee,
(e1, e2) -> e1.getAge() > e2.getAge() ? e1 : e2
));
Step 3: Display the Map
We print each entry in the resulting map:
employeeMap.forEach((name, employee) ->
System.out.println("Name: " + name + ", Employee: " + employee));
Conclusion
In Java 8, converting a list to a map is made simple using the Collectors.toMap() method. This allows you to define how to extract keys and values from list elements. Additionally, the method supports handling duplicate keys using a merge function. This flexibility makes it easy to work with lists and create maps that suit your application’s needs.