oxygenan
oxygenan

Reputation: 1033

Java 8 Streams - Map Output Not as expected

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();
    }
}

Upvotes: 1

Views: 153

Answers (1)

Amon
Amon

Reputation: 101

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

Upvotes: 2

Related Questions