Issue
I have a specific json value as shown below,
{
"record_id" : "r01",
"teacherNstudents": [
{
"teacher" : {
"name" : "tony",
"tid" : "T01"
},
"student" : {
"name" : "steve",
"sid" : "S01"
}
},
{
"teacher" : {
"name" : "tony",
"tid" : "T01"
},
"student" : {
"name" : "natasha",
"sid" : "S02"
}
},
{
"teacher" : {
"name" : "tony",
"tid" : "T01"
},
"student" : {
"name" : "bruce",
"sid" : "S03"
}
},
{
"teacher" : {
"name" : "tony",
"tid" : "T01"
},
"student" : {
"name" : "victor",
"sid" : "S04"
}
},
{
"teacher" : {
"name" : "henry",
"tid" : "T02"
},
"student" : {
"name" : "jack",
"sid" : "S05"
}
},
{
"teacher" : {
"name" : "henry",
"tid" : "T02"
},
"student" : {
"name" : "robert",
"sid" : "S06"
}
}
]
}
I am trying to generate a map like the one below,
[ {"S01", "T01"} , {"S05","T02"} ]
This is by removing all duplicate values and selecting only one teacher and student. The current code I wrote for this is
var firstMap = records.getTeacherNstudents()
.stream()
.collect(Collectors.toMap(tS -> tS.getTeacher().getTid(),
tS -> tS.getStudent().getSid(),
(a1, a2) -> a1));
return firstMap.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
I believe this can be improved, by using Collectors.groupingBy
. I am still working on it, but if anyone has any good idea on how to solve this, please share.
Solution
Using Java 8 groupingBy
You can try the below approach in order to have the Map<String,List<String>>
or Map<String,Set<String>>
(avoid duplicates) where key of map will be the teacher id and value as List or Set of Students corresponding to each teacher.
I have used groupingBy
feature from java 8 and did the grouping based on the tId and before collecting it, I have downstream it to List or Set of student Ids corresponding to each tId.
Approach A: Map<String,Set< String >> (Uniques)
data.getTeacherStudentMappingList()
.stream()
.collect(Collectors.groupingBy(x -> x.getTeacher().getTid(), LinkedHashMap::new,
Collectors.mapping(y -> y.getStudent().getSid(),Collectors.toSet())));
Approach B : Map<String,List< String >> (Non-uniques, duplicates)
data.getTeacherStudentMappingList()
.stream()
.collect(Collectors.groupingBy(x -> x.getTeacher().getTid(), LinkedHashMap::new,
Collectors.mapping(y -> y.getStudent().getSid(),Collectors.toList())));
Here,
data
is the converted object from the given json.LinkedHashmap::new
is used to preserve the order of student data from the json in the output.collectors.mapping
is used to convert the values corresponding to each key into the student ids.Collectors.toList()
will collect the list of student ids in the list.Collectors.toSet()
will collect the unique student ids in the set.
Output:
{T01=[S01, S02, S03, S04], T02=[S05, S06]}
Answered By - girdhar
Answer Checked By - David Goodson (JavaFixing Volunteer)