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.