Reputation: 76
I have a Exam table like this:
Exam
student_id | exam_date | status
1 2016-01-01 absence
2 2016-01-28 pass
3 2016-02-03 absence
1 2016-02-08 pass
4 2016-02-22 pass
5 2016-02-27 pass
6 2016-02-28 fail
5 2016-03-01 fail
3 2016-03-24 fail
7 2016-03-30 pass
This should be my 'Map of Integer, Decimal' result after stream:
Month, Rate
[1, 1.00]
[2, 0.75]
[3, 0.33]
Rate = pass / pass + fail
For now I have this following code working, but I have to change Collectors.counting()
with the Rate formula:
repository.findAllLastYearExames()
.stream().collect(Collectors.groupingBy(Exam::getMonthExam, Collectors.counting()));
Upvotes: 2
Views: 262
Reputation: 93872
One way to do that is to filter in first place the exams where the status is not pass or fail and then use averagingDouble
where you will return 1 for an exam that passes and 0 for an exam that fails to compute the average.
import static java.util.stream.Collectors.averagingDouble;
import static java.util.stream.Collectors.groupingBy;
...
Map<Integer, Double> map =
examList.stream()
//or filter to have a status that is either PASS or FAIL instead
.filter(e -> e.getStatus() != Exam.Status.ABSENCE)
.collect(groupingBy(Exam::getMonthExam,
averagingDouble(e -> e.getStatus() == Exam.Status.PASS ? 1 : 0)));
Upvotes: 1