I try to get a Map with Collectors.groupingBy() but I have no idea how to create…
I have a List from jpa jquerydsl
List<Tuple> list = mydata
the data is like
[memberId=1, departmentId=1]
[memberId=1, departmentId=2]
[memberId=2, departmentId=3]
[memberId=3, departmentId=4]
this is my Member class
public class Member {
private Long id;
private List<Long> departmentIds;
}
I want to parse tuple list to member Map By member id
data is like
Map<Long, Member>
{
1=Member(id=1, departmentIds=[1,2]),
2=Member(id=2, departmentIds=[3]),
3=Member(id=3, departmentIds=[4])
}
this is my code without Collectors.groupingBy()
Map<Long, Member> map = new HashMap<>();
for (Tuple tuple : tupleList) {
Long id = tuple.get(member.id); // this is jpa querydsl type
Long departmentId = tuple.get(department.id); // this is jpa querydsl type
if (map.containsKey(id)) {
Member member = map.get(id);
List<Long> departmentIds = member.getDepartmentIds();
departmentIds.add(departmentId);
member.setDepartmentIds(departmentIds);
map.put(id, member);
} else {
Member member = new Member();
member.setId(id);
List<Long> departmentIds = new ArrayList<>();
departmentIds.add(departmentId);
Member.setDepartmentIds(departmentIds);
map.put(id, member);
}
}
I want to refactor my code with Collectors.groupingBy()
tupleList.stream.collect(groupingBy( mapping())) ..
But I have no idea
How to create ? thanks…!
Advertisement
Answer
Maybe this code answers your question
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Scratch {
public static void main(String[] args) {
List<Pair<Long, Long>> myData = List.of(
Pair.<Long, Long>of(1L, 1L),
Pair.<Long, Long>of(1L, 2L),
Pair.<Long, Long>of(1L, 4L),
Pair.<Long, Long>of(2L, 3L),
Pair.<Long, Long>of(3L, 4L)
);
final Map<Long, Member> memberMap = myData.stream()
.collect(Collectors.toMap(Pair::getKey,
pair -> new Member(pair.getKey(), pair.getValue()),
(member1, member2) -> member1.addAllDepartmentId(member2.departmentIds)
));
System.out.println(memberMap);
}
public static class Member {
private Long id;
private List<Long> departmentIds;
public Member(Long id, Long departmentId) {
this.id = id;
this.departmentIds = new ArrayList<>();
this.departmentIds.add(departmentId);
}
public Member addAllDepartmentId(List<Long> departmentId) {
this.departmentIds.addAll(departmentId);
return this;
}
@Override
public String toString() {
return "Member{" +
"id=" + id +
", departmentIds=" + departmentIds +
'}';
}
}
}
The code prints
{1=Member{id=1, departmentIds=[1, 2, 4]}, 2=Member{id=2, departmentIds=[3]}, 3=Member{id=3, departmentIds=[4]}}
Which I think is what you want. I used org.apache.commons.lang3.tuple.Pair
where you have another tuple class. A added some helper methods to the Member
class to make the code a bit cleaner. The trick is using toMap
and supplying a merge function here (member1, member2) -> member1.addAllDepartmentId(member2.departmentIds)
to combine the department IDs.