I'm getting familiar with the Stream API and facing some problems.
Here is my code.
class Student {
String name;
int height;
LocalDate dob;
Map<String, Integer> scores;
public Student(String name, int height, LocalDate dob, Map<String, Integer> scores) {
this.name = name;
this.height = height;
this.dob = dob;
this.scores = scores;
}
// getters, setters and toString ...
}
public static void main(String [] args) {
LocalDate dob1 = LocalDate.of(2000, 1, 1);
LocalDate dob2 = LocalDate.of(2001, 2, 10);
LocalDate dob3 = LocalDate.of(2001, 3, 15);
LocalDate dob4 = LocalDate.of(2002, 4, 18);
LocalDate dob5 = LocalDate.of(2002, 5, 19);
Map<String, Integer> scores1 = new HashMap<String, Integer>();
scores1.put("Math", 100);
scores1.put("Physics", 95);
scores1.put("Chemistry", 90);
scores1.put("Biology", 100);
Map<String, Integer> scores2 = new HashMap<String, Integer>();
scores2.put("Math", 90);
scores2.put("Physics", 55);
scores2.put("Chemistry", 95);
scores2.put("Biology", 85);
Map<String, Integer> scores3 = new HashMap<String, Integer>();
scores3.put("Math", 85);
scores3.put("Physics", 50);
scores3.put("Chemistry", 100);
scores3.put("Biology", 75);
Map<String, Integer> scores4 = new HashMap<String, Integer>();
scores4.put("Math", 50);
scores4.put("Physics", 45);
scores4.put("Chemistry", 88);
scores4.put("Biology", 40);
Map<String, Integer> scores5 = new HashMap<String, Integer>();
scores5.put("Math", 65);
scores5.put("Physics", 100);
scores5.put("Chemistry", 88);
scores5.put("Biology", 55);
Student s1 = new Student("Tom", 6, dob1, scores1);
Student s2 = new Student("Dan", 7, dob2, scores2);
Student s3 = new Student("Ron", 5, dob3, scores3);
Student s4 = new Student("Pete", 5, dob4, scores4);
Student s5 = new Student("Sam", 6, dob5, scores5);
List<Student> students = new ArrayList<Student>();
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
students.add(s5);
}
From the above List<Student> I am trying to generate and print a map Map<String, <Map<String, Integer>> containing students with the highest score in each subject in the format <subject_name, <student_name, Score>>
So far I was able to come up with a solution shown below.
public static void printStudentWithHighestScoreInEachSubject(List<Student> S) {
HashMap<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();
List<String> sub = S.get(0).getScores().keySet().stream().collect(Collectors.toList());
for (String subj : sub) {
HashMap<String, Integer> t = new HashMap<String,Integer>();
for (Student s: S) {
Integer score = s.getScores().get(subj);
t.put(s.getName(), score);
}
map.put(subj, t);
}
HashMap<String, Map.Entry<String, Integer>> res = (HashMap<String, Map.Entry<String, Integer>>) map.entrySet().stream().collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue().entrySet().stream().max((x1, x2) -> x1.getValue().compareTo(x2.getValue())).get()));
System.out.println(res);
}
I am trying to come up with a solution that does not uses the for loops and handles everything using the Stream API.