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.