Java 8 Stream convert List to Map
Below example shows how to convert a List
to Map
in Java 8 using Stream. Suppose we have a List
of students and we want to construct a Map
with key
as student rollnumber and value
as student name,
you can do it as below:
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Student { private int rollNumber; private String name; private int age; Student (int rollNumber, String name, int age) { this.rollNumber = rollNumber; this.name = name; this.age = age; } // removed getters and setter for brevity @Override public String toString() { return "Student [rollNumber=" + rollNumber + ", name=" + name + ", age="+ age + "]"; } }
// Converts List to Map using Java 8 Collectors toMap() method public class ListToMapConverter { public static void main(String[] args) { List<Student> students = new ArrayList<Student>(); students.add(new Student(1, "John", 13)); students.add(new Student(2, "Mark", 14)); students.add(new Student(3, "Henry", 13)); Stream<Student> studentStream = students.stream(); Map<Integer, String> rollNumberNameMap = studentStream.collect(Collectors.toMap(Student::getRollNumber, Student::getName)); System.out.println(rollNumberNameMap); } }
Output :
{1=John, 2=Mark, 3=Henry}
Suppose you have duplicate keys and you create a Map from the List of Student, you will get
IllegalStateException
(Duplicate Key).
// Throws IllegalStateException public class ListToMapConverter { public static void main(String[] args) { List<Student> students = new ArrayList<Student>(); students.add(new Student(1, "John", 13)); students.add(new Student(2, "Mark", 14)); students.add(new Student(3, "Henry", 13)); students.add(new Student(1, "James", 15)); //oops student with same rollNumber Map<Integer, String> rollNumberNameMap = students.stream().collect(Collectors.toMap(Student::getRollNumber, Student::getName)); System.out.println(rollNumberNameMap); } }
Output :
Exception in thread "main" java.lang.IllegalStateException: Duplicate key John at java.util.stream.Collectors.lambda$throwingMerger$0(Unknown Source) at java.util.HashMap.merge(Unknown Source)
To resolve duplicate key isse, you need to pass mergeFunction
as an argument that will resolve collision between values.
public class ListToMapConverter { public static void main(String[] args) { // create students list Stream<Student> studentStream = students.stream(); Map<Integer, String> rollNumberNameMap = studentStream.collect(Collectors.toMap(Student::getRollNumber, Student::getName, (k1, k2) -> {return k1;})); System.out.println(rollNumberNameMap); } }
Output :
{1=John, 2=Mark, 3=Henry}
Another example that shows how to convert List to Map with key as rollNumber and value as List of Students.
public class ListToMapConverter { public static void main(String[] args) { // create students list Map<Integer, List<Student>> rollNumberNameMap = students.stream().collect(Collectors.toMap(Student::getRollNumber, Function.identity())); System.out.println(rollNumberNameMap); rollNumberNameMap = students.stream().collect(Collectors.toMap(Student::getRollNumber, p -> p)); System.out.println(rollNumberNameMap); } }
Console Output :
{1=Student [rollNumber=1, name=John, age=13], 2=Student [rollNumber=2, name=Mark, age=14], 3=Student [rollNumber=3, name=Henry, age=13]} {1=Student [rollNumber=1, name=John, age=13], 2=Student [rollNumber=2, name=Mark, age=14], 3=Student [rollNumber=3, name=Henry, age=13]}
References :
Oracle Docs Collectors
Oracle Docs Comparator Collectors groupingBy()