Learn to collect stream elements into Map using Collectors.toMap() and Collectors.groupingBy() methods using Java 8 Stream APIs. Convert stream to map using Java stream APIs.
1. Stream Elements with unique map keys – Collectors.toMap()
If the stream elements have the unique map key field then we can use Collectors.toMap()
to collect elements to map in Map<keyObj, Element>
format easily.
For example, we can collect a list of Employee
objects to map in where employee ids are unique fields and used a key to map entries.
Java 8 example to convert list to map using stream APIs.
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Employee> employeeList = new ArrayList<>(Arrays.asList( new Employee(1, "A", 100), new Employee(2, "A", 200), new Employee(3, "B", 300), new Employee(4, "B", 400), new Employee(5, "C", 500), new Employee(6, "C", 600))); Map<Long, Employee> employeesMap = employeeList.stream() .collect( Collectors.toMap(Employee::getId, Function.identity()) ); System.out.println(employeesMap); } }
Program output.
{1=Employee [id=1, name=A, salary=100.0], 2=Employee [id=2, name=A, salary=200.0], 3=Employee [id=3, name=B, salary=300.0], 4=Employee [id=4, name=B, salary=400.0], 5=Employee [id=5, name=C, salary=500.0], 6=Employee [id=6, name=C, salary=600.0]}
2. Stream Elements with duplicate map keys – Collectors.groupingBy()
If the stream elements have elements where map keys are duplicate the we can use Collectors.groupingBy()
to collect elements to map in Map<keyObj, List<Element>>
format. Here for each map key, we will store all elements in a list as map value.
For example, we can collect a list of Employee
objects to map in where employee names may be duplicate fields for some stream elements. In such case, all employees with same name will be stored in a list, and list will be stored as map value field.
Java 8 example to convert list to map of lists using stream APIs.
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Employee> employeeList = new ArrayList<>(Arrays.asList( new Employee(1, "A", 100), new Employee(2, "A", 200), new Employee(3, "B", 300), new Employee(4, "B", 400), new Employee(5, "C", 500), new Employee(6, "C", 600))); Map<String, List<Employee>> employeesMap = employeeList.stream() .collect(Collectors.groupingBy(Employee::getName)); System.out.println(employeesMap); } }
Program output.
{A=[Employee [id=1, name=A, salary=100.0], Employee [id=2, name=A, salary=200.0]], B=[Employee [id=3, name=B, salary=300.0], Employee [id=4, name=B, salary=400.0]], C=[Employee [id=5, name=C, salary=500.0], Employee [id=6, name=C, salary=600.0]]}
3. Conclusion
It is very important to know beforehand if the Stream
elements will have the distinct value for the map key field or not. If map keys are duplicate and we use Collectors.toMap()
method, we will get the IllegalStateException:
Exception in thread "main" java.lang.IllegalStateException: Duplicate key Employee [id=5, name=C, salary=500.0] at java.util.stream.Collectors.lambda$throwingMerger$106(Collectors.java:133) at java.util.stream.Collectors$$Lambda$3/149928006.apply(Unknown Source) at java.util.HashMap.merge(HashMap.java:1245)
Happy Learning !!
If you wish to create map from list by id, but list contains duplicates you can use Collectors.toMap with BinnaryOperator:
The console output will be:
Thanks for sharing.