Below is Student class definition :
class Student{
String name;
int sub1;
int sub2;
int sub3;
// etc...etc...
}
I have list of all students. Requirement is to get average of sub1, sub2 and sub3. And also get min mark and max mark in any subject for any student.
Below is the code for sub1:
IntSummaryStatistics sub1Summary = students.stream().collect(Collectors.summarizingInt(s -> s.sub1));
Is it possible to do with single expression or I will have to create IntSummaryStatisticsfor each subject and compare each lowest and highest subj value?
Thanks in advance
Try following :
List<Student> students = Arrays.asList(Student.create("A", 60, 55, 35),
Student.create("B", 40, 65, 75),
Student.create("C", 70, 45, 95));
Map<String, IntSummaryStatistics> subjectsSummary = new HashMap<String, IntSummaryStatistics>();
Map<String, List<Integer>> subjectMarks = new HashMap<String, List<Integer>>();
List<Integer> sub1Marks = new ArrayList<>();
List<Integer> sub2Marks = new ArrayList<>();
List<Integer> sub3Marks = new ArrayList<>();
// Input : Student
// Output : Map(Key=SubjectName, Value= List of Marks for students)
Function<Student, Map<String, List<Integer>>> toSubjectsMap = (s) -> {
sub1Marks.add(s.getSub1());
sub2Marks.add(s.getSub2());
sub3Marks.add(s.getSub3());
subjectMarks.put("Sub1", sub1Marks);
subjectMarks.put("Sub2", sub2Marks);
subjectMarks.put("Sub3", sub3Marks);
return subjectMarks;
};
//Function to generate summary stats from the list of integers/marks
Function<List<Integer>, IntSummaryStatistics> generateStatsFunc = (listOfMarks) -> {
return listOfMarks.stream().collect(Collectors.summarizingInt(marks->marks));
};
// 1. Students are mapped to generate Map for subject-->List of Marks
// 2. Doing flatMap on the generate Map to get the Keys from the map(list of subjects)
// 3. Collecting the Keys(Subject Names) of Map to Map(Key=SubjectName,Value=IntSummaryStats for Subject)
students.stream().map(toSubjectsMap).flatMap(subMap -> subMap.keySet().stream())
.collect(() -> subjectsSummary/* Initial Value of Map */, (summary, key) -> {
// Generate the stats from the list of marks for the subject
IntSummaryStatistics st = generateStatsFunc.apply(subjectMarks.get(key));
//Adding the stats for each Subject into the result Summary
summary.put(key, st);
} , (summary1, summary2) -> {
//merging the two maps
summary1.putAll(summary2);
});
System.out.println(subjectsSummary);
and Student class as follows :
class Student {
String name;
int sub1;
int sub2;
int sub3;
static Student create(String name, int sub1, int sub2, int sub3) {
// validation
return new Student(name, sub1, sub2, sub3);
}
public String getName() {
return name;
}
public int getSub1() {
return sub1;
}
public int getSub2() {
return sub2;
}
public int getSub3() {
return sub3;
}
private Student(String name, int sub1, int sub2, int sub3) {
this.name = name;
this.sub1 = sub1;
this.sub2 = sub2;
this.sub3 = sub3;
}
@Override
public String toString() {
return name;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With