Reputation: 247
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())
));
Upvotes: 10
Views: 2927
Reputation: 846
then answer provided by @Eran is straight forward but if you want to change the data type in this context String
to Long
then you can use lamda expression
to convert String
to Long
Map<Long, List<Student>> map =
list.stream()
.collect(Collectors.groupingBy(s ->Long.parseLong(s.getId())));
Upvotes: 0
Reputation: 2212
As alternative of groupingBy
using toMap
:
Map<Long, List<Student>> result = list.stream()
.collect(Collectors.toMap(Student::getId,
s-> { List<Student> l = new ArrayList<>();
l.add(s);
return l;
},
(l1,l2)-> { l1.addAll(l2);
return l1;}));
Upvotes: 0
Reputation: 21975
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);
Upvotes: 4
Reputation: 79075
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()));
Upvotes: 6
Reputation: 393821
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));
Upvotes: 14