I have the following class:
public class StudentGrade {
int studentId;
double value;
Date date;
...
}
I would like to get the max grade by student as a map (studentId -> StudentGrade)
public Map<Integer, StudentGrade> getMaxGradeByStudent(List<StudentGrade> grades) {
Map<Integer, Optional<StudentGrade>> maxGrades = grades.stream().collect(
Collectors.groupingBy(
StudentGrade::getStudentId,
Collectors.maxBy(Comparator.comparing(StudentGrade::getValue)))
);
Map<Integer, StudentGrade> finalGrades = new HashMap<>();
maxGrades.entrySet().forEach(entry -> {
entry.getValue().ifPresent(value -> finalGrades.put(entry.getKey(), value));
})
}
Is there a better way to do this? I would like to avoid having to initialize a new Hashmap and use streams for everything.
CodePudding user response:
You can use toMap
instead of groupingBy
, and BinaryOperator
instead of Collectors.maxBy
, like:
public Map<Integer, StudentGrade> getMaxGradeByStudent(List<StudentGrade> grades) {
return grades.stream()
.collect(Collectors.toMap(StudentGrade::getStudentId,
x -> x, // Or Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(StudentGrade::getValue))));
}
CodePudding user response:
You can use this if you'd like to avoid streams
public Map<Integer, StudentGrade> getMaxGradeByStudent(List<StudentGrade> grades) {
Map<Integer, StudentGrade> studentIdToMaxGrade = new HashMap<>();
for (StudentGrade grade : grades) {
studentIdToMaxGrade.merge(
grade.getStudentId(),
grade,
BinaryOperator.maxBy(Comparator.comparing(StudentGrade::getValue))
);
}
return studentIdToMaxGrade;
}