Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a list of objects to Map<Long, List<>> using streams

I want to convert a list of Student objects to Map<Long, List<>> using streams.

List<Student> list = new ArrayList<Student>();
list.add(new Student("1", "test 1"));
list.add(new Student("3", "test 1"));
list.add(new Student("3", "test 3"));

I want the final outcome in the following way:

Map

Key: 1

Value List: Student("1", "test 1")

Key: 3

Value List: Student("3", "test 1"), Student("3", "test 3")

I tried the following code, but it is reinitializing the Student objects. Can anyone help me fix the below code?

Map<Long, List<Student>> map = list.stream()
                        .collect(Collectors.groupingBy(
                                Student::getId,
                                Collectors.mapping(Student::new, Collectors.toList())
                        ));
like image 993
Ann Avatar asked Apr 28 '21 05:04

Ann


People also ask

How do you convert a List of objects into a stream of objects?

Converting a list to stream is very simple. As List extends the Collection interface, we can use the Collection. stream() method that returns a sequential stream of elements in the list.

Can we convert List to Map in Java?

With Java 8, you can convert a List to Map in one line using the stream() and Collectors. toMap() utility methods. The Collectors. toMap() method collects a stream as a Map and uses its arguments to decide what key/value to use.

Which method is used to convert stream to List?

This class has the toList() method, which converts the Stream to a List.


3 Answers

You don't need to chain the mapping collector. The single argument groupingBy will give you a Map<Long, List<Student>> by default.

Map<Long, List<Student>> map = 
    list.stream()
        .collect(Collectors.groupingBy(Student::getId));
like image 108
Eran Avatar answered Oct 28 '22 13:10

Eran


The answer by Eran is spot-on. Just to add to that, you can also use a Supplier e.g.

Map<Long, List<Student>> map = 
    list.stream()
        .collect(Collectors.groupingBy(Student::getId, TreeMap::new, Collectors.toList()));
like image 21
Arvind Kumar Avinash Avatar answered Oct 28 '22 15:10

Arvind Kumar Avinash


For these kind of easy use cases, I prefer to look at Eclipse Collections instead of relying on the overhead of creating a Stream.

The result is the same, it gives you a java.util.Map and I find the syntax more concise

MutableList<Student> list = Lists.mutable.of();
list.add(new Student("1", "test 1"));
list.add(new Student("3", "test 1"));
list.add(new Student("3", "test 3"));

Map<String, List<Student>> map = list.groupBy(Student::getId).toMap(ArrayList::new);
like image 43
Yassin Hajaj Avatar answered Oct 28 '22 15:10

Yassin Hajaj