1

I am trying to find the student names and their attendance status using

map streaming.

After trying multiple changes below is the code snippet

created and its current Output:

2021-06-25 [2021-06-25=HO, 2021-06-25=HL, 2021-06-25=PR]
2021-06-24 [2021-06-24=PR, 2021-06-24=PR, 2021-06-24=AB]
2021-06-23 [2021-06-23=PR, 2021-06-23=PR, 2021-06-23=PR]
2021-06-22 [2021-06-22=PR, 2021-06-22=AB, 2021-06-22=LB]
2021-06-21 [2021-06-21=AB, 2021-06-21=LB, 2021-06-21=PR]
2021-06-20 [2021-06-20=PR, 2021-06-20=PR, 2021-06-20=PR]

The expected Output needed is as below

2021-06-25 [John=HO, Max=HL, Mike=PR]
2021-06-24 [John=PR, Max=PR, Mike=AB]
2021-06-23 [John=PR, Max=PR, Mike=PR]
2021-06-22 [John=PR, Max=AB, Mike=LB]
2021-06-21 [John=AB, Max=LB, Mike=PR]
2021-06-20 [John=PR, Max=PR, Mike=PR]

Java code created so far for the program execution is as below

TestStreams

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class TestStreams {

    public static void main(String[] args) {

        List<CourseData> coursesList = addDataToCourses();
        YearMonth fromDate = YearMonth.of(2021, 6);
        YearMonth toDate = YearMonth.of(2021, 7);
        coursesList.stream()
                .filter((course) -> course.getMonth().compareTo(fromDate) >= 0 || course.getMonth().compareTo(toDate) <= 0)
                .flatMap(month -> month.getStudentList().stream())
                .flatMap(student -> student.getAttendanceData().entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey)).forEach((a, b) -> System.out.println(a + " " + b));

    }

    private static List<CourseData> addDataToCourses() {
        List<CourseData> coursesList = new ArrayList<>();
        coursesList.add(addCourse1("John", "US", getMapDates1()));
        coursesList.add(addCourse1("Max", "UK", getMapDates2()));
        coursesList.add(addCourse1("Micke", "Mexico", getMapDates3()));
        return coursesList;
    }

    private static Map<LocalDate, String> getMapDates1() {
        Map<LocalDate, String> mapDates1 = new TreeMap<>();
        mapDates1.put(LocalDate.of(2021, 6, 20), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 21), "AB");
        mapDates1.put(LocalDate.of(2021, 6, 22), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 23), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 24), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 25), "HO");
        return mapDates1;
    }

    private static Map<LocalDate, String> getMapDates2() {
        Map<LocalDate, String> mapDates1 = new TreeMap<>();
        mapDates1.put(LocalDate.of(2021, 6, 20), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 21), "LB");
        mapDates1.put(LocalDate.of(2021, 6, 22), "AB");
        mapDates1.put(LocalDate.of(2021, 6, 23), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 24), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 25), "HL");
        return mapDates1;
    }

    private static Map<LocalDate, String> getMapDates3() {
        Map<LocalDate, String> mapDates1 = new TreeMap<>();
        mapDates1.put(LocalDate.of(2021, 6, 20), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 21), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 22), "LB");
        mapDates1.put(LocalDate.of(2021, 6, 23), "PR");
        mapDates1.put(LocalDate.of(2021, 6, 24), "AB");
        mapDates1.put(LocalDate.of(2021, 6, 25), "PR");
        return mapDates1;
    }

    private static CourseData addCourse1(String name, String ctry, Map<LocalDate, String> mapDates) {
        CourseData course1 = new CourseData();
        List<StudentInfo> studentList1 = new ArrayList<StudentInfo>();
        StudentInfo student1 = new StudentInfo();
        student1.setName(name);
        student1.setCountry(ctry);
        student1.setAttendanceData(mapDates);
        studentList1.add(student1);
        course1.setMonth("Jun 21");
        course1.setStudentList(studentList1);
        return course1;
    }
}

StudentInfo

class StudentInfo {

    private String name;
    private String country;
    private Map<LocalDate, String> attendanceData = new TreeMap<>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public Map<LocalDate, String> getAttendanceData() {
        return attendanceData;
    }

    public void setAttendanceData(Map<LocalDate, String> attendanceData) {
        this.attendanceData = attendanceData;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("StudentInfo [name=").append(name).append(", country=").append(country)
                .append(", attendanceData=").append(attendanceData).append("]");
        return builder.toString();
    }

}

CourseData

class CourseData {

    private YearMonth month;
    private Integer courseDays;
    private List<StudentInfo> studentList;

    public YearMonth getMonth() {
        return month;
    }

    public void setMonth(String month) {

        DateTimeFormatter df = DateTimeFormatter.ofPattern("MMM yy");
        YearMonth dt = YearMonth.parse(month, df);
        setCourseDays(dt.lengthOfMonth());
        this.month = dt;

    }

    public Integer getCourseDays() {
        return courseDays;
    }

    public void setCourseDays(Integer courseDays) {
        this.courseDays = courseDays;
    }

    public List<StudentInfo> getStudentList() {
        return studentList;
    }

    public void setStudentList(List<StudentInfo> studentList) {
        this.studentList = studentList;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("CourseData [month=").append(month).append(", courseDays=").append(courseDays)
                .append(", studentList=").append(studentList).append("]");
        return builder.toString();
    }
}
4
  • 1
    It's immensely difficult for us to debug your code without seeing the code. Please provide a minimal reproducible example. Commented Jul 13, 2021 at 20:28
  • @Slaw: Had added the program, missed out initially Commented Jul 13, 2021 at 20:32
  • I have looked over your code and although the desired output could be achieved I believe your relationships between classes could be improved. I would think that CourseData should not have anything to do with students but limited to course data such as names, dates, available slots, instructor, etc. And storing information in lists of Map.Entries would be better replaced by individual fields in a speclal class with meaningfully named getters. Key and value fields outside of a mapping context doesn't say much about what is going on. Commented Jul 13, 2021 at 22:07
  • 1
    Thanks @WJS ,actually i had come up with these names to avoid the actual class names Commented Jul 14, 2021 at 18:28

1 Answer 1

2

You were losing student info at second flatmap .flatMap(student -> student.getAttendanceData().entrySet().stream()).

This solves the case (with addition of StudentAttendance class):

public static void main(String[] args) {

    List<CourseData> coursesList = addDataToCourses();
    YearMonth fromDate = YearMonth.of(2021, 6);
    YearMonth toDate = YearMonth.of(2021, 7);
    coursesList.stream()
            .filter((course) -> course.getMonth().compareTo(fromDate) >= 0 || course.getMonth().compareTo(toDate) <= 0)
            .flatMap(month -> month.getStudentList().stream())
            .flatMap(student -> student.getAttendanceData().entrySet().stream()
                    .map(entry -> new StudentAttendance(student.getName(), entry.getKey(), entry.getValue()))
                    .collect(Collectors.toList())
                    .stream())
            .collect(Collectors.groupingBy(StudentAttendance::getLocalDate))
            .forEach((a, b) -> System.out.println(a + " " + b));

}

class StudentAttendance{
    private String name;
    private LocalDate localDate;
    private String courseName;

    public StudentAttendance(String name, LocalDate localDate, String courseName) {
        this.name = name;
        this.localDate = localDate;
        this.courseName = courseName;
    }

    public String getName() {
        return name;
    }

    public LocalDate getLocalDate() {
        return localDate;
    }

    public String getNameWithCourseName() {
        return name + '=' + courseName;
    }
}

With output:

2021-06-25 John=HO Max=HL Micke=PR
2021-06-24 John=PR Max=PR Micke=AB
2021-06-23 John=PR Max=PR Micke=PR
2021-06-22 John=PR Max=AB Micke=LB
2021-06-21 John=AB Max=LB Micke=PR
2021-06-20 John=PR Max=PR Micke=PR
Sign up to request clarification or add additional context in comments.

1 Comment

,Appreciate the answer, it gave the expected output!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.