Java 8 个流 - 地图输出不符合预期

Java 8 Streams - Map Output Not as expected

我正在尝试使用

查找学生姓名和他们的出勤状态

地图流。

在尝试多次更改后,下面是代码片段

已创建及其当前输出:

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]

所需的预期输出如下

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 目前为程序执行创建的代码如下

测试流

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

学生信息

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

}

课程数据

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

您在第二个平面图 .flatMap(student -> student.getAttendanceData().entrySet().stream()) 丢失了学生信息。

这解决了这个问题(加上 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;
    }
}

输出:

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