一、前言
通过最后这三次的大作业这学期对Java课程的学习已经接近尾声,我了解了Java的编译环境如JDK、JRE等等,Java去掉了C++语言的许多功能,是安全的、解释的、高性能的语言,但最主要的还是Java的面向对象性,Java中的类与对象的创建以及类间关系,类与类之间方法属性的调用时常让我头疼,通过pta的练习我也对Java语法知识点更加熟悉并且更进一步了解了Java中的继承关系、抽象类与接口:
(1)继承关系
Java中的继承是一种面向对象编程的重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。
Java中的继承通过关键字“extends”实现。子类通过“extends”关键字后指定父类的名称来继承父类。例如:
```
public class Animal {
public void eat() {
System.out.println("Animal is eating...");
}
}
public class Cat extends Animal {
public void meow() {
System.out.println("Cat is meowing...");
}
}
```
在上述代码中,Cat类通过“extends”关键字指定Animal类作为其父类,并继承了Animal类的“eat”方法。此外,Cat类还定义了自己的方法“meow”。
接下来,我们可以通过创建Cat类对象来使用“eat”和“meow”方法:
```
public class Main {
public static void main(String args[]) {
Cat myCat = new Cat();
myCat.eat(); // 调用Animal类的eat方法
myCat.meow(); // 调用Cat类的meow方法
}
}
```
在上述代码中,我们创建了一个Cat类对象“myCat”,并调用了它的“eat”和“meow”方法。由于Cat类继承Animal类的“eat”方法,因此Cat类对象可以使用Animal类中定义的“eat”方法。
继承允许在不重复编写相同代码的情况下扩展和修改现有代码,从而提高了代码的可重用性和可维护性。
(2)抽象类
在Java中,抽象类是一种不能被实例化的类,它只能作为其他类的父类来使用。抽象类可以包含抽象方法和具体方法,其中抽象方法是只有定义,而没有实现的方法,而具体方法则是有实现的方法。
使用抽象类可以实现一种基于约定的编程方式。抽象类定义了一些方法的接口,要求派生类实现这些方法。因此,抽象类实现了一种行为的规范,而具体的实现则由派生类来完成。
在Java中,使用“abstract”关键字来定义抽象类和抽象方法。例如:
```
public abstract class Shape {
int x, y;
public Shape(int x, int y) {
this.x = x;
this.y = y;
}
public void move(int deltaX, int deltaY) {
x += deltaX;
y += deltaY;
}
public abstract double getArea();
}
```
在上述代码中,Shape类是一个抽象类,它包含了一个构造函数和两个具体方法“move”和抽象方法“getArea”。
由于Shape类含有抽象方法,因此它不能被实例化。只有定义了这些抽象方法的具体实现的类才能被实例化。例如:
```
public class Rectangle extends Shape {
int width, height;
public Rectangle(int x, int y, int width, int height) {
super(x, y);
this.width = width;
this.height = height;
}
@Override
public double getArea() {
return width * height;
}
}
```
在上述代码中,Rectangle类扩展了Shape类并实现了抽象方法“getArea”。
抽象类提供了一种抽象层次结构,可以有效地组织和管理程序中的对象类型,并确保代码的可维护性和可扩展性。
(3)接口
在Java中,接口是一种定义方法规范的抽象类型,它定义了一组方法,但没有提供任何实现。接口提供了一种行为的规范,而具体的实现则由实现了接口的类来完成。
使用Java接口可以实现多态性,这意味着相同的接口可以由不同的类来实现,并提供不同的实现方法。
在Java中,使用“interface”关键字来定义接口。例如:
```
public interface Drawable {
void draw();
}
```
在上述代码中,Drawable是一个接口,它定义了一个抽象方法“draw”。
要实现一个接口,需要使用“implements”关键字。例如:
```
public class Circle implements Drawable {
private int x, y, radius;
public Circle(int x, int y, int radius) {
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle at (" + x + ", " + y + ") with radius " + radius);
}
}
```
在上述代码中,Circle类实现了Drawable接口,并提供了“draw”方法的具体实现。因此,我们可以使用Circle类对象调用“draw”方法。
接口可以被多重继承,这意味着一个接口可以通过继承其他接口来定义更复杂的行为规范。
Java接口提供了一种灵活的机制,可以使程序更易于扩展和维护,并提高代码的可读性和可重用性。
(4)ArrayList
在 Java 中,ArrayList 是一个动态数组,实现了 List 接口。ArrayList 允许在运行时动态添加和删除元素,可以包含重复的元素。
ArrayList 内部使用一个数组来存储数据,当数组元素数量达到容量时,自动增加容量。默认情况下,ArrayList 的容量为 10。
以下是一些常见的 ArrayList 操作:
1. 在尾部添加元素:`list.add(element)`
2. 在指定位置插入元素:`list.add(index, element)`
3. 删除元素:`list.remove(index)` 或 `list.remove(element)`
4. 获取元素:`list.get(index)`
5. 获取元素个数:`list.size()`
6. 判断 ArrayList 是否为空:`list.isEmpty()`
7. 清空 ArrayList:`list.clear()`
二、设计与分析
(1)课程成绩统计程序-1
这是课程成绩统计的第一大题,
- 定义类和数据结构
- 
我们需要定义两个类:Course类和Grade类,分别表示课程和成绩信息。 Course类包含以下属性: - String name:课程名称
- String type:课程性质,取值为"必修"或"选修"
- String mode:考核方式,取值为"考试"或"考察"
 Grade类包含以下属性: - String id:学号,8位数字组成
- String name:姓名,不超过10个字符
- String courseName:课程名称
- int dailyGrade:平时成绩,可选
- int finalGrade:期末成绩,必选
 我们可以使用一个List来存储所有的Course对象,使用一个Map来存储所有的Grade对象,键为学号,值为该学生所有的Grade对象列表。 - 读取输入数据
 首先,我们需要从标准输入读取数据。可以使用Scanner类,按行读取输入数据,直到读到"end"为止。 在读取过程中,我们需要先解析每个课程的信息,将其存储为一个Course对象,然后将其添加到Course对象列表中。 接着,我们需要解析每个成绩信息,将其存储为一个Grade对象,然后将其添加到相应学生的Grade对象列表中。 在解析输入数据的过程中,需要注意以下几点: - 检查课程性质和考核方式是否匹配
- 检查平时成绩和期末成绩的范围是否在[0,100]之间
- 检查学号是否为8位数字
- 检查姓名、课程名称是否超过10个字符
- 检查重复的课程/成绩信息,只保留第一个信息,忽略后面输入的
- 如果出现异常情况,需要输出相应的错误信息并结束程序
 - 计算学生总成绩平均分
 遍历所有的Grade对象,按学生分组计算每个学生的总成绩平均分。可以使用一个Map来存储每个学生的总成绩平均分,键为学号,值为总成绩平均分。最后按学号从小到大排序输出结果。 - 计算单门课程成绩平均分
 遍历所有的Grade对象,按课程分组计算每门课程的平时成绩平均分、期末考试平均分、总成绩平均分。可以使用一个Map来存储每门课程的平时成绩平均分、期末考试平均分、总成绩平均分,键为课程名称,值为一个长度为3的数组,分别表示平时成绩平均分、期末考试平均分、总成绩平均分。最后按课程名称的字符顺序输出结果。 - 计算班级所有课程总成绩平均分
 遍历所有的Grade对象,按班级分组计算每个班级的所有课程总成绩平均分。可以使用一个Map来存储每个班级的所有课程总成绩平均分,键为班级号,值为总成绩平均分。最后按班级号从小到大排序输出结果。 
import java.text.Collator;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // 课程信息列表
        ArrayList<Course> courses = new ArrayList<>();
        // 学生成绩列表
        ArrayList<Grade> grades = new ArrayList<>();
        String[] courseType = {"必修", "选修"};
        String[] courseMode = {"考察", "考试"};
        ArrayList<String> courseTypeCollect = new ArrayList<>(Arrays.asList(courseType));
        ArrayList<String> courseModeCollect = new ArrayList<>(Arrays.asList(courseMode));
        input:
        while (input.hasNext()) {
            String line = input.nextLine();
            if (line.isEmpty() || line.equals("end")) {
                break;
            }
            // 解析输入行,获取课程/成绩信息
            String[] fields = line.trim().split("\\s+");
            try {
                // 判断输入类型:课程信息 or 成绩信息
                if (fields.length == 3) { // 课程信息
                    String name = fields[0];
                    String type = String.valueOf(fields[1]);
                    String mode = String.valueOf(fields[2]);
                    //判断正确输入
                    if (name.length() > 10 || !courseTypeCollect.contains(type) || !courseModeCollect.contains(mode)) {
                        System.out.println("wrong format");
                        continue;
                    }
                    boolean isCor = true;
                    if (type.equals("必修") && !mode.equals("考试")) {
                        System.out.println(name + " " + ":" + " course type & access mode mismatch");
                        System.out.println(name + " does not exist");
                        isCor = false;
                    }
                    // 向课程信息列表中添加新的课程对象
                    Course course = new Course(name, type, mode, isCor);
                    for (Course cours : courses) {
                        if (cours.getName().equals(name))
                            continue input;
                    }
                    courses.add(course);
                } else if (fields.length == 5) { // 成绩信息
                    String sid = fields[0];
                    String name = fields[1];
                    String cname = fields[2];
                    int dailyGrade = Integer.parseInt(fields[3]);
                    int finalGrade = Integer.parseInt(fields[4]);
                    //判断正确输入
                    if (sid.length() != 8 || name.length() > 10 || cname.length() > 10) {
                        System.out.println("wrong format");
                        continue;
                    }
                    //重复的成绩信息
                    for (Grade grade : grades) {
                        if (grade.getCourse().getName().equals(cname) && grade.getSID().equals(sid)) {
                            continue input;
                        }
                    }
                    // 在课程信息列表中查找当前成绩对应的课程对象
                    Course course = null;
                    for (Course c : courses) {
                        if (c.getName().equals(cname)) {
                            course = c;
                            break;
                        }
                    }
                    // 如果课程对象为空,则输出错误信息并进入下一次输入
                    if (course == null) {
                        System.out.println(sid + " " + name + " :" + cname + " does not exist");
                        grades.add(new Grade(sid, name, new Course("","","",false), 0, 0));
                        continue;
                    }
                    //成绩越界
                    if (finalGrade < 0 || finalGrade > 100 || dailyGrade < 0 || dailyGrade > 100) {
                        System.out.println("wrong format");
                        continue;
                    }
                    // 检查成绩数量和考核方式是否匹配
                    if (!course.getMode().equals("考试")) {
                        System.out.println(sid + " " + name + " : access mode mismatch");
                        grades.add(new Grade(sid, name, course, 0, 0));
                        continue;
                    }
                    // 向成绩列表中添加新的成绩对象
                    grades.add(new Grade(sid, name, course, dailyGrade, finalGrade));
                } else if (fields.length == 4) { // 考察
                    String sid = fields[0];
                    String name = fields[1];
                    String cname = fields[2];
                    int finalGrade = Integer.parseInt(fields[3]);
                    //重复的成绩信息
                    for (Grade grade : grades) {
                        if (grade.getCourse().getName().equals(cname) && grade.getSID().equals(sid)) {
                            continue input;
                        }
                    }
                    // 在课程信息列表中查找当前成绩对应的课程对象
                    Course course = null;
                    for (Course c : courses) {
                        if (c.getName().equals(cname)) {
                            course = c;
                            break;
                        }
                    }
                    // 如果课程对象为空,则输出错误信息并进入下一次输入
                    if (course == null) {
                        System.out.println(sid + " " + name + " :" + cname + " does not exist");
                        grades.add(new Grade(sid, name, new Course("","","",false), 0, 0));
                        continue;
                    }
                    //成绩越界
                    if (finalGrade < 0 || finalGrade > 100) {
                        System.out.println("wrong format");
                        continue;
                    }
                    // 检查成绩数量和考核方式是否匹配
                    if (course.getMode().equals("考试")) {
                        System.out.println(sid + " " + name + " : access mode mismatch");
                        grades.add(new Grade(sid, name, course, 0, 0));
                        continue;
                    }
                    // 向成绩列表中添加新的成绩对象
                    grades.add(new Grade(sid, name, course, 0, finalGrade));
                } else { // 格式错误
                    System.out.println("wrong format");
                }
            } catch (IllegalArgumentException e) {
                System.out.println("wrong format");
            }
        }
        // 1、学生课程总成绩平均分按学号由低到高排序输出
        Map<String, Student> students = new HashMap<>();
        for (Grade grade : grades) {
            int totalGrade = grade.getTotalGrade();
            Student student = students.getOrDefault(grade.getSID(), new Student(grade.getSID(), grade.getName()));
            student.add((grade.getCourse().getisCor() ? totalGrade : 0), grade.getCourse().getType());
            students.put(grade.getSID(), student);
        }
        List<Student> studentList = new ArrayList<>(students.values());
        Collections.sort(studentList);
        for (Student student : studentList) {
            String sid = student.getSID();
            String name = student.getName();
            int avgGrade = student.getAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(sid + " " + name + " did not take any exams");
            } else {
                System.out.println(sid + " " + name + " " + avgGrade);
            }
        }
        // 2、单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出
        Map<String, ClassStat> classStats = new HashMap<>();
        //某一门课程没有成绩
        for (Course cours : courses) {
            if (grades.size() == 0)
                System.out.println(cours.getName() + " has no grades yet");
            for (int i = 0; i < grades.size(); i++) {
                if (grades.get(i).getCourse().equals(cours))
                    break;
                if (i == grades.size() - 1)
                    System.out.println(cours.getName() + " has no grades yet");
            }
        }
        for (Grade grade : grades) {
            if (!grade.getCourse().getisCor())
                continue;
            String className = grade.getCourse().getName();
            ClassStat stat = classStats.getOrDefault(className, new ClassStat(className));
            stat.addGrade(grade.getTotalGrade());
            stat.addDailyGrade(grade.getDailyGrade());
            stat.addFinalGrade(grade.getFinalGrade());
            classStats.put(className, stat);
        }
        List<ClassStat> classStatList = new ArrayList<>(classStats.values());
        Collections.sort(classStatList);
        for (ClassStat stat : classStatList) {
            String ClassName = stat.getClassName();
            int avgGrade = stat.getAvgGrade();
            int dailyGrade = stat.getDailyAvgGrade();
            int finalGrade = stat.getFinalAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(ClassName + " has no grades yet");
            } else {
                System.out.println(ClassName + " " + (dailyGrade == 0 ? "" : dailyGrade + " ") + finalGrade + " " + stat.getAvgGrade());
            }
        }
        // 3、班级所有课程总成绩平均分按班级由低到高排序输出
        Map<String, ClassStat> classStats1 = new HashMap<>();
        for (Grade grade : grades) {
            int totalGrade = grade.getTotalGrade();
            String classID = grade.getSID().substring(0, 6);
            ClassStat stat = classStats1.getOrDefault(classID, new ClassStat(classID));
            stat.addGrade((grade.getCourse().getisCor() ? totalGrade : 0));
            classStats1.put(classID, stat);
        }
        List<ClassStat> classStatList1 = new ArrayList<>(classStats1.values());
        Collections.sort(classStatList1);
        for (ClassStat stat : classStatList1) {
            String classID = stat.getClassName();
            int avgGrade = stat.getAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(classID + " has no grades yet");
            } else {
                System.out.println(classID + " " + avgGrade);
            }
        }
    }
    static class ClassStat implements Comparable<ClassStat> {
        private String className;
        private int gradeSum;
        private int courseCount;
        private int dailyGradeSum;
        private int dailyCourseCount;
        private int finalGradeSum;
        private int finalCourseCount;
        public ClassStat(String classID) {
            this.className = classID;
            this.gradeSum = 0;
            this.courseCount = 0;
            this.dailyGradeSum = 0;
            this.dailyCourseCount = 0;
            this.finalGradeSum = 0;
            this.finalCourseCount = 0;
        }
        public String getClassName() {
            return className;
        }
        public void addGrade(int grade) {
            gradeSum += grade;
            if (grade > 0)
                courseCount++;
        }
        public void addDailyGrade(int grade) {
            dailyGradeSum += grade;
            dailyCourseCount++;
        }
        public void addFinalGrade(int grade) {
            finalGradeSum += grade;
            finalCourseCount++;
        }
        public int getDailyAvgGrade() {
            if (dailyCourseCount == 0) {
                return -1;
            } else {
                return dailyGradeSum / dailyCourseCount;
            }
        }
        public int getFinalAvgGrade() {
            if (finalCourseCount == 0) {
                return -1;
            } else {
                return finalGradeSum / finalCourseCount;
            }
        }
        public int getAvgGrade() {
            if (courseCount == 0) {
                return -1;
            } else {
                return gradeSum / courseCount;
            }
        }
        @Override
        public int compareTo(ClassStat other) {
            Collator collator = Collator.getInstance(Locale.CHINA);
            return collator.getCollationKey(className).compareTo(collator.getCollationKey(other.getClassName()));
        }
    }
    static class Course {
        private String name;
        private String type;
        private String mode;
        private boolean isCor;
        public boolean getisCor() {
            return isCor;
        }
        public Course(String name, String type, String mode, boolean isCor) {
            this.name = name;
            this.type = type;
            this.mode = mode;
            this.isCor = isCor;
        }
        public String getName() {
            return name;
        }
        public String getType() {
            return type;
        }
        public String getMode() {
            return mode;
        }
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Course)) {
                return false;
            }
            Course other = (Course) obj;
            return name.equals(other.name) && type == other.type && mode == other.mode;
        }
        @Override
        public int hashCode() {
            return Objects.hash(name, type, mode);
        }
    }
    static class Grade implements Comparable<Grade> {
        private String sid;
        private String name;
        private Course course;
        private int dailyGrade;
        private int finalGrade;
        public Grade(String sid, String name, Course course, int dailyGrade, int finalGrade) {
            this.sid = sid;
            this.name = name;
            this.course = course;
            this.dailyGrade = dailyGrade;
            this.finalGrade = finalGrade;
        }
        public String getSID() {
            return sid;
        }
        public String getName() {
            return name;
        }
        public Course getCourse() {
            return course;
        }
        public int getDailyGrade() {
            return dailyGrade;
        }
        public int getFinalGrade() {
            return finalGrade;
        }
        public int getTotalGrade() {
            return course.getMode().equals("考察") ? finalGrade : dailyGrade * 30 / 100 + finalGrade * 70 / 100;
        }
        public boolean hasDailyGrade() {
            return course.getMode().equals("考试") && dailyGrade > 0 && dailyGrade < 100;
        }
        @Override
        public int compareTo(Grade other) {
            return sid.compareTo(other.sid);
        }
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Grade)) {
                return false;
            }
            Grade other = (Grade) obj;
            return sid.equals(other.sid) && course.equals(other.course);
        }
        @Override
        public int hashCode() {
            return Objects.hash(sid, course);
        }
        @Override
        public String toString() {
            return sid + " " + name + " " + course.getName() + " " + dailyGrade + " " + finalGrade;
        }
    }
    static class Student implements Comparable<Student> {
        private String sid;
        private String name;
        private int gradeSum;
        private int courseCount;
        private int requiredSum;
        private int electiveSum;
        private int requiredCount;
        private int electiveCount;
        public Student(String sid, String name) {
            this.sid = sid;
            this.name = name;
            this.gradeSum = 0;
            this.courseCount = 0;
            this.requiredSum = 0;
            this.electiveSum = 0;
            this.requiredCount = 0;
            this.electiveCount = 0;
        }
        public String getSID() {
            return sid;
        }
        public String getName() {
            return name;
        }
        public void add(int grade, String type) {
            gradeSum += grade;
            if (grade > 0)
                courseCount++;
            if (type.equals("选修") && grade > 0) {
                requiredSum += grade;
                requiredCount++;
            } else if (type.equals("必修") && grade > 0) {
                electiveSum += grade;
                electiveCount++;
            }
        }
        public int getAvgGrade() {
            if (courseCount == 0) {
                return -1;
            } else {
                return gradeSum / courseCount;
            }
        }
        @Override
        public int compareTo(Student other) {
            return sid.compareTo(other.sid);
        }
    }
}


1.设计数据结构
首先需要设计数据结构存储课程信息和成绩信息。为简化代码实现,可以使用Java中的Map数据结构进行存储,具体如下:
课程信息:
Map<String, Map<String, String>> courseMap = new HashMap<>();
// key为课程名称,value为存储课程性质和考核方式的Map
成绩信息:
Map<String, Map<String, List<Integer>>> scoreMap = new HashMap<>();
// key为课程名称,value为存储成绩信息的Map,其中value中的List依次保存每次成绩
2.解析输入信息
对于每个输入的信息,需要对其进行解析并进行相应的处理,包括输入格式判断、存储课程信息和成绩信息、以及异常处理等。
可以将每种输入信息的解析分别封装成不同的方法,方便对输入信息进行处理,避免代码过于复杂和冗长。
3.计算不同统计数据并输出结果
在得到所有成绩信息后,需要统计出所需要的几个数据并输出结果。这些数据包括:
学生所有课程总成绩的平均分
单门课程成绩平均分(包括平时成绩、期末考试成绩和总成绩)
班级所有课程总成绩平均分
可以将计算不同数据的操作分别封装成不同的方法,方便代码实现和管理。输出结果时,需要按照题目要求进行格式化输出,包括空格、排序等。
4.异常处理
在代码实现中,必须注意对各种异常情况进行处理,包括成绩范围、输入格式、课程名称等输入错误等。需要及时抛出异常或输出错误信息,以保证程序正常执行。
5.总体流程
通过上述步骤的实现,可以得到整个程序的总体流程如下:
初始化存储课程信息和成绩信息的Map
循环读取输入信息
对于每种输入信息,进行解析并进行相应的处理
在得到所有成绩信息后,计算出需要统计的数据并进行输出
根据题目要求进行格式化输出
总体实现过程比较复杂,需要对各种细节仔细思考和处理,需要仔细调试才能保证程序的正确执行。
import java.text.Collator;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // 课程信息列表
        ArrayList<Course> courses = new ArrayList<>();
        // 学生成绩列表
        ArrayList<Grade> grades = new ArrayList<>();
        String[] courseType = {"必修", "选修", "实验"};
        String[] courseMode = {"考察", "考试", "实验"};
        ArrayList<String> courseTypeCollect = new ArrayList<>(Arrays.asList(courseType));
        ArrayList<String> courseModeCollect = new ArrayList<>(Arrays.asList(courseMode));
        input:
        while (input.hasNext()) {
            String line = input.nextLine();
            if (line.isEmpty() || line.equals("end")) {
                break;
            }
            // 解析输入行,获取课程/成绩信息
            String[] fields = line.trim().split("\\s+");
            try {
                // 判断输入类型:课程信息 or 成绩信息
                if (fields.length == 3) { // 课程信息
                    String name = fields[0];
                    String type = String.valueOf(fields[1]);
                    String mode = String.valueOf(fields[2]);
                    //判断正确输入
                    if (name.length() > 10 || !courseTypeCollect.contains(type) || !courseModeCollect.contains(mode)) {
                        System.out.println("wrong format");
                        continue;
                    }
                    boolean isCor = true;
                    if (type.equals("必修") && !mode.equals("考试")) {
                        System.out.println(name + " " + ":" + " course type & access mode mismatch");
//                        System.out.println(name + " does not exist");
                        continue;
                    } else if (type.equals("实验") && !mode.equals("实验")) {
                        System.out.println(name + " " + ":" + " course type & access mode mismatch");
//                        System.out.println(name + " does not exist");
                        continue;
                    }
                    // 向课程信息列表中添加新的课程对象
                    Course course = new Course(name, type, mode, isCor);
                    for (Course cours : courses) {
                        if (cours.getName().equals(name))
                            continue input;
                    }
                    courses.add(course);
                } else if (fields.length == 5) { // 成绩信息
                    String sid = fields[0];
                    String name = fields[1];
                    String cname = fields[2];
                    int dailyGrade = Integer.parseInt(fields[3]);
                    int finalGrade = Integer.parseInt(fields[4]);
                    //判断正确输入
                    if (sid.length() != 8 || name.length() > 10 || cname.length() > 10) {
                        System.out.println("wrong format");
                        continue;
                    }
                    //重复的成绩信息
                    for (Grade grade : grades) {
                        if (grade.getCourse().getName().equals(cname) && grade.getSID().equals(sid)) {
                            continue input;
                        }
                    }
                    // 在课程信息列表中查找当前成绩对应的课程对象
                    Course course = null;
                    for (Course c : courses) {
                        if (c.getName().equals(cname)) {
                            course = c;
                            break;
                        }
                    }
                    // 如果课程对象为空,则输出错误信息并进入下一次输入
                    if (course == null) {
                        System.out.println(sid + " " + name + " :" + cname + " does not exist");
                        grades.add(new Grade(sid, name, new Course("", "", "", false), 0, 0));
                        continue;
                    }
                    //成绩越界
                    if (finalGrade < 0 || finalGrade > 100 || dailyGrade < 0 || dailyGrade > 100) {
                        System.out.println("wrong format");
                        continue;
                    }
                    // 检查成绩数量和考核方式是否匹配
                    if (!course.getMode().equals("考试")) {
                        System.out.println(sid + " " + name + " : access mode mismatch");
                        grades.add(new Grade(sid, name, course, 0, 0));
                        continue;
                    }
                    // 向成绩列表中添加新的成绩对象
                    grades.add(new Grade(sid, name, course, dailyGrade, finalGrade));
                } else if (fields.length == 4) { // 考察
                    String sid = fields[0];
                    String name = fields[1];
                    String cname = fields[2];
                    int finalGrade = Integer.parseInt(fields[3]);
                    //重复的成绩信息
                    for (Grade grade : grades) {
                        if (grade.getCourse().getName().equals(cname) && grade.getSID().equals(sid)) {
                            continue input;
                        }
                    }
                    // 在课程信息列表中查找当前成绩对应的课程对象
                    Course course = null;
                    for (Course c : courses) {
                        if (c.getName().equals(cname)) {
                            course = c;
                            break;
                        }
                    }
                    // 如果课程对象为空,则输出错误信息并进入下一次输入
                    if (course == null) {
                        System.out.println(sid + " " + name + " :" + cname + " does not exist");
                        grades.add(new Grade(sid, name, new Course("", "", "", false), 0, 0));
                        continue;
                    }
                    //成绩越界
                    if (finalGrade < 0 || finalGrade > 100) {
                        System.out.println("wrong format");
                        continue;
                    }
                    // 检查成绩数量和考核方式是否匹配
                    if (course.getMode().equals("考试")) {
                        System.out.println(sid + " " + name + " : access mode mismatch");
                        grades.add(new Grade(sid, name, course, 0, 0));
                        continue;
                    }
                    // 向成绩列表中添加新的成绩对象
                    grades.add(new Grade(sid, name, course, 0, finalGrade));
                } else if (fields.length > 5) { // 实验
                    String sid = fields[0];
                    String name = fields[1];
                    String cname = fields[2];
                    if (Integer.parseInt(fields[3]) < 4 || Integer.parseInt(fields[3]) > 9) {
                        System.out.println("wrong format");
                        continue;
                    }
                    int totalGrade = 0;
                    for (int i = 4; i < fields.length; i++) {
                        int grade = Integer.parseInt(fields[i]);
                        if (grade < 0 || grade > 100) {
                            System.out.println("wrong format");
                            continue input;
                        }
                        totalGrade += grade;
                    }
                    //重复的成绩信息
                    for (Grade grade : grades) {
                        if (grade.getCourse().getName().equals(cname) && grade.getSID().equals(sid)) {
                            continue input;
                        }
                    }
                    // 在课程信息列表中查找当前成绩对应的课程对象
                    Course course = null;
                    for (Course c : courses) {
                        if (c.getName().equals(cname)) {
                            course = c;
                            break;
                        }
                    }
                    // 如果课程对象为空,则输出错误信息并进入下一次输入
                    if (course == null) {
                        System.out.println(sid + " " + name + " :" + cname + " does not exist");
                        grades.add(new Grade(sid, name, new Course("", "", "", false), 0, 0));
                        continue;
                    }
                    // 检查成绩数量和考核方式是否匹配
                    if ((fields.length - 4) != Integer.parseInt(fields[3])) {
                        System.out.println(sid + " " + name + " : access mode mismatch");
                        grades.add(new Grade(sid, name, new Course("", "", "", false), 0, 0));
                        continue;
                    }
                    // 向成绩列表中添加新的成绩对象
                    grades.add(new Grade(sid, name, course, 0, totalGrade / Integer.parseInt(fields[3])));
                } else { // 格式错误
                    System.out.println("wrong format");
                }
            } catch (IllegalArgumentException e) {
                System.out.println("wrong format");
            }
        }
        // 1、学生课程总成绩平均分按学号由低到高排序输出
        Map<String, Student> students = new HashMap<>();
        for (Grade grade : grades) {
            int totalGrade = grade.getTotalGrade();
            Student student = students.getOrDefault(grade.getSID(), new Student(grade.getSID(), grade.getName()));
            student.add((grade.getCourse().getisCor() ? totalGrade : 0), grade.getCourse().getType());
            students.put(grade.getSID(), student);
        }
        List<Student> studentList = new ArrayList<>(students.values());
        Collections.sort(studentList);
        for (Student student : studentList) {
            String sid = student.getSID();
            String name = student.getName();
            int avgGrade = student.getAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(sid + " " + name + " did not take any exams");
            } else {
                System.out.println(sid + " " + name + " " + avgGrade);
            }
        }
        // 2、单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出
        Map<String, ClassStat> classStats = new HashMap<>();
        //某一门课程没有成绩
        for (Course cours : courses) {
            if (grades.size() == 0)
                System.out.println(cours.getName() + " has no grades yet");
            for (int i = 0; i < grades.size(); i++) {
                if (grades.get(i).getCourse().equals(cours))
                    break;
                if (i == grades.size() - 1)
                    System.out.println(cours.getName() + " has no grades yet");
            }
        }
        for (Grade grade : grades) {
            if (!grade.getCourse().getisCor())
                continue;
            String className = grade.getCourse().getName();
            ClassStat stat = classStats.getOrDefault(className, new ClassStat(className));
            stat.addGrade(grade.getTotalGrade());
            stat.addDailyGrade(grade.getDailyGrade());
            if (!grade.getCourse().getType().equals("实验"))
                stat.addFinalGrade(grade.getFinalGrade());
            classStats.put(className, stat);
        }
        List<ClassStat> classStatList = new ArrayList<>(classStats.values());
        Collections.sort(classStatList);
        for (ClassStat stat : classStatList) {
            String ClassName = stat.getClassName();
            int avgGrade = stat.getAvgGrade();
            int dailyGrade = stat.getDailyAvgGrade();
            int finalGrade = stat.getFinalAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(ClassName + " has no grades yet");
            } else {
                System.out.println(ClassName + " " + (dailyGrade == 0 ? "" : dailyGrade + " ") + (finalGrade == -1 ? "" : finalGrade + " ") + stat.getAvgGrade());
            }
        }
        // 3、班级所有课程总成绩平均分按班级由低到高排序输出
        Map<String, ClassStat> classStats1 = new HashMap<>();
        for (Grade grade : grades) {
            int totalGrade = grade.getTotalGrade();
            String classID = grade.getSID().substring(0, 6);
            ClassStat stat = classStats1.getOrDefault(classID, new ClassStat(classID));
            stat.addGrade((grade.getCourse().getisCor() ? totalGrade : 0));
            classStats1.put(classID, stat);
        }
        List<ClassStat> classStatList1 = new ArrayList<>(classStats1.values());
        Collections.sort(classStatList1);
        for (ClassStat stat : classStatList1) {
            String classID = stat.getClassName();
            int avgGrade = stat.getAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(classID + " has no grades yet");
            } else {
                System.out.println(classID + " " + avgGrade);
            }
        }
    }
    static class ClassStat implements Comparable<ClassStat> {
        private String className;
        private int gradeSum;
        private int courseCount;
        private int dailyGradeSum;
        private int dailyCourseCount;
        private int finalGradeSum;
        private int finalCourseCount;
        public ClassStat(String classID) {
            this.className = classID;
            this.gradeSum = 0;
            this.courseCount = 0;
            this.dailyGradeSum = 0;
            this.dailyCourseCount = 0;
            this.finalGradeSum = 0;
            this.finalCourseCount = 0;
        }
        public String getClassName() {
            return className;
        }
        public void addGrade(int grade) {
            gradeSum += grade;
            if (grade > 0)
                courseCount++;
        }
        public void addDailyGrade(int grade) {
            dailyGradeSum += grade;
            dailyCourseCount++;
        }
        public void addFinalGrade(int grade) {
            finalGradeSum += grade;
            finalCourseCount++;
        }
        public int getDailyAvgGrade() {
            if (dailyCourseCount == 0) {
                return -1;
            } else {
                return dailyGradeSum / dailyCourseCount;
            }
        }
        public int getFinalAvgGrade() {
            if (finalCourseCount == 0) {
                return -1;
            } else {
                return finalGradeSum / finalCourseCount;
            }
        }
        public int getAvgGrade() {
            if (courseCount == 0) {
                return -1;
            } else {
                return gradeSum / courseCount;
            }
        }
        @Override
        public int compareTo(ClassStat other) {
            Collator collator = Collator.getInstance(Locale.CHINA);
            return collator.getCollationKey(className).compareTo(collator.getCollationKey(other.getClassName()));
        }
    }
    static class Course {
        private String name;
        private String type;
        private String mode;
        private boolean isCor;
        public boolean getisCor() {
            return isCor;
        }
        public Course(String name, String type, String mode, boolean isCor) {
            this.name = name;
            this.type = type;
            this.mode = mode;
            this.isCor = isCor;
        }
        public String getName() {
            return name;
        }
        public String getType() {
            return type;
        }
        public String getMode() {
            return mode;
        }
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Course)) {
                return false;
            }
            Course other = (Course) obj;
            return name.equals(other.name) && type == other.type && mode == other.mode;
        }
        @Override
        public int hashCode() {
            return Objects.hash(name, type, mode);
        }
    }
    static class Grade implements Comparable<Grade> {
        private String sid;
        private String name;
        private Course course;
        private int dailyGrade;
        private int finalGrade;
        public Grade(String sid, String name, Course course, int dailyGrade, int finalGrade) {
            this.sid = sid;
            this.name = name;
            this.course = course;
            this.dailyGrade = dailyGrade;
            this.finalGrade = finalGrade;
        }
        public String getSID() {
            return sid;
        }
        public String getName() {
            return name;
        }
        public Course getCourse() {
            return course;
        }
        public int getDailyGrade() {
            return dailyGrade;
        }
        public int getFinalGrade() {
            return finalGrade;
        }
        public int getTotalGrade() {
            return !course.getMode().equals("考试") ? finalGrade : (dailyGrade * 30 + finalGrade * 70) / 100;
        }
        public boolean hasDailyGrade() {
            return course.getMode().equals("考试") && dailyGrade > 0 && dailyGrade < 100;
        }
        @Override
        public int compareTo(Grade other) {
            return sid.compareTo(other.sid);
        }
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Grade)) {
                return false;
            }
            Grade other = (Grade) obj;
            return sid.equals(other.sid) && course.equals(other.course);
        }
        @Override
        public int hashCode() {
            return Objects.hash(sid, course);
        }
        @Override
        public String toString() {
            return sid + " " + name + " " + course.getName() + " " + dailyGrade + " " + finalGrade;
        }
    }
    static class Student implements Comparable<Student> {
        private String sid;
        private String name;
        private int gradeSum;
        private int courseCount;
        private int requiredSum;
        private int electiveSum;
        private int requiredCount;
        private int electiveCount;
        public Student(String sid, String name) {
            this.sid = sid;
            this.name = name;
            this.gradeSum = 0;
            this.courseCount = 0;
            this.requiredSum = 0;
            this.electiveSum = 0;
            this.requiredCount = 0;
            this.electiveCount = 0;
        }
        public String getSID() {
            return sid;
        }
        public String getName() {
            return name;
        }
        public void add(int grade, String type) {
            gradeSum += grade;
            if (grade > 0)
                courseCount++;
            if (type.equals("选修") && grade > 0) {
                requiredSum += grade;
                requiredCount++;
            } else if (type.equals("必修") && grade > 0) {
                electiveSum += grade;
                electiveCount++;
            }
        }
        public int getAvgGrade() {
            if (courseCount == 0) {
                return -1;
            } else {
                return gradeSum / courseCount;
            }
        }
        @Override
        public int compareTo(Student other) {
            return sid.compareTo(other.sid);
        }
    }
}


(3)课程成绩统计程序-3
这使课程成绩统计第三大题,
- 定义数据结构
首先要定义数据结构来存储输入的课程和成绩信息,如Course、Grade、Student等类。Course类包括课程名称、课程性质、考核方式等属性;Grade类包括学号、姓名、课程名称、平时成绩、期末成绩、实验次数、每次实验成绩等属性;Student类包括学号、姓名、成绩列表等属性。
- 解析输入信息
接下来需要解析输入的课程和成绩信息,根据输入信息的格式进行解析,将解析出来的信息存储到对应的数据结构中。解析的过程中需要注意异常情况的处理,如格式错误、课程名称不在已输入的课程列表中等。
- 计算成绩
根据不同的考核方式和课程性质,计算每门课程的总成绩。其中必修课程只能选择考试方式,选修课程可以选择考试或考察方式,实验课程只能选择实验方式。计算总成绩时需要考虑平时成绩和期末成绩的权重。
- 按要求输出结果
最后按照要求输出结果,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分等。在输出结果时需要注意排序和异常情况的处理。如果某个学生没有任何成绩信息,需要输出特定的提示信息。如果某个班级没有任何成绩信息,也需要输出特定的提示信息。
import java.text.Collator;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // 课程信息列表
        ArrayList<Course> courses = new ArrayList<>();
        // 学生成绩列表
        ArrayList<Grade> grades = new ArrayList<>();
        String[] courseType = {"必修", "选修", "实验"};
        String[] courseMode = {"考察", "考试", "实验"};
        ArrayList<String> courseTypeCollect = new ArrayList<>(Arrays.asList(courseType));
        ArrayList<String> courseModeCollect = new ArrayList<>(Arrays.asList(courseMode));
        input: while (input.hasNext()) {
            String line = input.nextLine();
            if (line.isEmpty() || line.equals("end")) {
                break;
            }
            String[] fields = line.trim().split("\\s+");
            try {
                if (!isNumeric(fields[0])) { // 课程信息
                    //判断正确输入
                    if (fields[0].length() > 10 || !courseTypeCollect.contains(fields[1]) || !courseModeCollect.contains(fields[2])) {
                        System.out.println("wrong format");
                        continue;
                    }
                    Course course = null;
                    List<Float> weightList = new ArrayList<Float>();
                    switch (fields[2]) {
                        case "考试": {
                            if (fields.length != 5) {
                                System.out.println(fields[0] + " " + ":" + " course type & access mode mismatch");
                                continue input;
                            }
                            //权重不匹配
                            if (Float.parseFloat(fields[3]) + Float.parseFloat(fields[4]) != 1) {
                                System.out.println(fields[0] + " : weight value error");
                                continue input;
                            }
                            weightList.add(Float.valueOf(fields[3]));
                            weightList.add(Float.valueOf(fields[4]));
                            course = new Course(fields[0], fields[1], fields[2], weightList);
                            break;
                        }
                        case "考察": {
                            if (fields[1].equals("必修") || fields.length != 3) {
                                System.out.println(fields[0] + " " + ":" + " course type & access mode mismatch");
                                continue input;
                            }
                            course = new Course(fields[0], fields[1], fields[2], weightList);
                            break;
                        }
                        case "实验": {
                            if (!fields[1].equals("实验"))
                                System.out.println(fields[0] + " " + ":" + " course type & access mode mismatch");
                            int num = Integer.parseInt(fields[3]);
                            if (fields.length - 4 != num) {
                                System.out.println(fields[0] + " : number of scores does not match");
                                continue input;
                            }
                            if (fields.length < 8 || fields.length > 13)
                                System.out.println("wrong format");
                            Float sum = (float) 0;
                            for (int i = 4; i < fields.length; i++) {
                                sum += Float.parseFloat(fields[i]);
                                weightList.add(Float.parseFloat(fields[i]));
                            }
                            if (sum != 1) {
                                System.out.println(fields[0] + " : weight value error");
                                continue input;
                            }
                            course = new Course(fields[0], fields[1], fields[2], weightList);
                            break;
                        }
                    }
                    // 向课程信息列表中添加新的课程对象
                    for (Course cours : courses) {
                        if (cours.getName().equals(fields[0]))
                            continue input;
                    }
                    courses.add(course);
                } else if (isNumeric(fields[0])) { // 成绩信息
                    String sid = fields[0];
                    String name = fields[1];
                    String cname = fields[2];
                    List<Integer> gradeList = new ArrayList<>();
                    //判断正确输入
                    if (sid.length() != 8 || name.length() > 10 || cname.length() > 10) {
                        System.out.println("wrong format");
                        continue;
                    }
                    //重复的成绩信息
                    for (Grade grade : grades) {
                        if (grade.getCourse().getName().equals(cname) && grade.getSid().equals(sid)) {
                            continue input;
                        }
                    }
                    for (int i = 3; i < fields.length; i++) {
                        //成绩越界
                        if (Integer.parseInt(fields[i]) < 0 || Integer.parseInt(fields[i]) > 100) {
                            System.out.println("wrong format");
                            continue input;
                        }
                    }
                    // 在课程信息列表中查找当前成绩对应的课程对象
                    Course course = null;
                    for (Course c : courses) {
                        if (c.getName().equals(cname)) {
                            course = c;
                            break;
                        }
                    }
                    // 如果课程对象为空,则输出错误信息并进入下一次输入
                    if (course == null) {
                        System.out.println(sid + " " + name + " :" + cname + " does not exist");
//                        grades.add(new Grade(sid, name, new Course("", "", "", null), null));
                        continue;
                    }
                    // 检查成绩数量和考核方式是否匹配
                    switch (course.getMode()) {
                        case "考试": {
                            if (fields.length != 5) {
                                System.out.println(sid + " " + name + " " + ": access mode mismatch");
                                break;
                            }
                            gradeList.add(Integer.parseInt(fields[3]));
                            gradeList.add(Integer.parseInt(fields[4]));
                            break;
                        }
                        case "考察": {
                            if (fields.length > 5) {
                                System.out.println(sid + " " + name + " " + ": access mode mismatch");
                                break;
                            }
                            gradeList.add(fields.length == 4 ? Integer.parseInt(fields[3]) : Integer.parseInt(fields[4]));
//                            gradeList.add(Integer.parseInt(fields[3]));
                            break;
                        }
                        case "实验": {
                            if (fields.length - 3 != course.getWeight().size()) {
                                System.out.println(sid + " " + name + " " + ": access mode mismatch");
                                break;
                            }
                            for (int i = 3; i < fields.length; i++) {
                                gradeList.add(Integer.parseInt(fields[i]));
                            }
                            break;
                        }
                    }
                    // 向成绩列表中添加新的成绩对象
                    grades.add(new Grade(sid, name, course, gradeList));
                } else { // 格式错误
                    System.out.println("wrong format");
                }
            } catch (IllegalArgumentException e) {
                System.out.println("wrong format");
            }
        }
        // 1、学生课程总成绩平均分按学号由低到高排序输出
        Map<String, Student> students = new HashMap<>();
        for (Grade grade : grades) {
            int totalGrade = grade.getTotalGrade();
            Student student = students.getOrDefault(grade.getSid(), new Student(grade.getSid(), grade.getName()));
            student.add(totalGrade, grade.getCourse().getType());
            students.put(grade.getSid(), student);
        }
        List<Student> studentList = new ArrayList<>(students.values());
        Collections.sort(studentList);
        for (Student student : studentList) {
            String sid = student.getSID();
            String name = student.getName();
            int avgGrade = student.getAvgGrade();
            if (avgGrade == -1) {
                System.out.println(sid + " " + name + " did not take any exams");
            } else {
                System.out.println(sid + " " + name + " " + avgGrade);
            }
        }
        // 2、单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出
        Map<String, ClassStat> classStats = new HashMap<>();
        //某一门课程没有成绩
        for (Course cours : courses) {
            if (grades.size() == 0)
                System.out.println(cours.getName() + " has no grades yet");
            for (int i = 0; i < grades.size(); i++) {
                if (grades.get(i).getCourse().equals(cours))
                    break;
                if (i == grades.size() - 1) {
                    classStats.put(cours.getName(), new ClassStat(cours.getName()));
                }
            }
        }
        for (Grade grade : grades) {
            String className = grade.getCourse().getName();
            ClassStat stat = classStats.getOrDefault(className, new ClassStat(className));
            stat.addGrade(grade.getTotalGrade());
            classStats.put(className, stat);
        }
        List<ClassStat> classStatList = new ArrayList<>(classStats.values());
        Collections.sort(classStatList);
        for (ClassStat stat : classStatList) {
            String ClassName = stat.getClassName();
            int avgGrade = stat.getAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(ClassName + " has no grades yet");
            } else {
                System.out.println(ClassName + " " + stat.getAvgGrade());
            }
        }
        // 3、班级所有课程总成绩平均分按班级由低到高排序输出
        Map<String, ClassStat> classStats1 = new HashMap<>();
        for (Grade grade : grades) {
            int totalGrade = grade.getTotalGrade();
            String classID = grade.getSid().substring(0, 6);
            ClassStat stat = classStats1.getOrDefault(classID, new ClassStat(classID));
            stat.addGrade(totalGrade);
            classStats1.put(classID, stat);
        }
        List<ClassStat> classStatList1 = new ArrayList<>(classStats1.values());
        Collections.sort(classStatList1);
        for (ClassStat stat : classStatList1) {
            String classID = stat.getClassName();
            int avgGrade = stat.getAvgGrade();
            if (avgGrade == -1 || avgGrade == 0) {
                System.out.println(classID + " has no grades yet");
            } else {
                System.out.println(classID + " " + avgGrade);
            }
        }
    }
    static class ClassStat implements Comparable<ClassStat> {
        private String className;
        private int gradeSum;
        private int courseCount;
        public ClassStat(String classID) {
            this.className = classID;
            this.gradeSum = 0;
            this.courseCount = 0;
        }
        public String getClassName() {
            return className;
        }
        public void addGrade(int grade) {
            gradeSum += grade;
            if (grade >= 0)
                courseCount++;
        }
        public int getAvgGrade() {
            if (courseCount == 0) {
                return -1;
            } else {
                return gradeSum / courseCount;
            }
        }
        @Override
        public int compareTo(ClassStat other) {
            Collator collator = Collator.getInstance(Locale.CHINA);
            return collator.getCollationKey(className).compareTo(collator.getCollationKey(other.getClassName()));
        }
    }
    static class Course {
        private String name;
        private String type;
        private String mode;
        private List<Float> weight;
        public String getName() {
            return name;
        }
        public String getType() {
            return type;
        }
        public String getMode() {
            return mode;
        }
        public List<Float> getWeight() {
            return weight;
        }
        public Course(String name, String type, String mode, List<Float> weight) {
            this.name = name;
            this.type = type;
            this.mode = mode;
            this.weight = weight;
        }
        @Override
        public int hashCode() {
            return Objects.hash(name, type, mode);
        }
    }
    static class Grade implements Comparable<Grade> {
        private String sid;
        private String name;
        private Course course;
        private List<Integer> gradeList;
        public String getSid() {
            return sid;
        }
        public String getName() {
            return name;
        }
        public Course getCourse() {
            return course;
        }
        public List<Integer> getGradeList() {
            return gradeList;
        }
        public Grade(String sid, String name, Course course, List<Integer> gradeList) {
            this.sid = sid;
            this.name = name;
            this.course = course;
            this.gradeList = gradeList;
        }
        public int getTotalGrade() {
            int totalGrade = 0;
            if (gradeList.size() == 0) {
                return -1;
            }
            switch (course.getMode()) {
                case "考试": {
                    for (int i = 0; i < 2; i++) {
                        totalGrade += (course.getWeight().get(i) * gradeList.get(i));
                    }
                    break;
                }
                case "考察": {
                    totalGrade += gradeList.get(gradeList.size() - 1);
                    break;
                }
                case "实验": {
                    for (int i = 0; i < course.getWeight().size(); i++) {
                        totalGrade += (course.getWeight().get(i) * gradeList.get(i));
                    }
                    break;
                }
            }
            return totalGrade;
        }
        @Override
        public int compareTo(Grade other) {
            return sid.compareTo(other.sid);
        }
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Grade)) {
                return false;
            }
            Grade other = (Grade) obj;
            return sid.equals(other.sid) && course.equals(other.course);
        }
        @Override
        public int hashCode() {
            return Objects.hash(sid, course);
        }
}
    static class Student implements Comparable<Student> {
        private String sid;
        private String name;
        private int gradeSum;
        private int courseCount;
        public Student(String sid, String name) {
            this.sid = sid;
            this.name = name;
            this.gradeSum = 0;
            this.courseCount = 0;
        }
        public String getSID() {
            return sid;
        }
        public String getName() {
            return name;
        }
        public void add(int grade, String type) {
            gradeSum += grade;
            if (grade >= 0)
                courseCount++;
        }
        public int getAvgGrade() {
            if (courseCount == 0) {
                return -1;
            } else {
                return gradeSum / courseCount;
            }
        }
        @Override
        public int compareTo(Student other) {
            return sid.compareTo(other.sid);
        }
    }
    public static boolean isNumeric(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        // 判断是否满足数字格式的正则表达式
        String pattern = "^\\d+$";
        return str.matches(pattern);
    }
}


三、踩坑心得
(1)在7-1 课程成绩统计程序中,由于程序算法中循环结构过多,导致很多测试点报非零返回的错误,后来我更改了算法结构减少了循环结构的使用,很多的测试点非零返回的错误又不报错


四、主要困难及改进建议
(1)主要困难
- 
输入格式复杂,需要对每条输入进行解析和处理,容易出现格式错误和异常情况。 
- 
需要同时考虑多种情况,如权重默认值、考核方式、课程性质等,容易出现逻辑错误和漏洞。 
- 
输出结果需要排序和处理异常情况,容易出现输出错误和不完整的结果。 
(2)改进建议
- 
采用面向对象的设计原则,例如单一职责原则、开闭原则等,按照类的功能进行设计和划分,避免出现代码混乱和逻辑错误。 
- 
增加单元测试和异常处理机制,对程序进行全面的测试和验证,提高程序的健壮性和可靠性。 
- 优化算法和数据结构,提高程序的效率和性能。
五、总结
Java 中的继承、抽象类和接口都是面向对象编程中非常重要的概念,以下是我对它们的总结和学习心得:
1. 继承:继承是指一个类从另一个类继承(拥有)其属性和方法。继承是实现类之间的 IS-A 关系,使得代码的复用性更高。继承可以通过 `extends` 关键字来实现。在继承的过程中,子类可以通过覆盖或重写方法来改变父类的行为。
学习心得:继承是 Java 中的一个重要概念,熟练掌握继承关系可以提高代码的重用性和可维护性。在实际编程中,需要谨慎设计类之间的继承关系,遵循开闭原则等设计原则。
2. 抽象类:抽象类是一种通过声明抽象方法和具体方法来定义接口和形式的类。抽象类不能被实例化,只能作为子类的基类存在。抽象类可以通过 `abstract` 关键字来定义。抽象类强制子类必须提供实现的方法,从而使得具体子类能够符合规范,更加可靠。
学习心得:抽象类在代码重用和约束子类方面非常有用,可以明确子类必须要实现的方法接口。在实际开发中,需要注意抽象类和接口的使用场景区别,避免不当使用。
3. 接口:接口是一种具有一组抽象方法和常量的数据类型,可以看作是一个协议或规范。接口提供了一种与实现独立的一致性方式,允许不同的类实现相同的方法,实现了类之间的行为规范,使得程序的可扩展性更强。接口可以通过 `interface` 关键字来定义,实现类可以通过 `implements` 关键字来实现接口。
学习心得:接口提供了一种非常灵活的方式来定义行为的规范,适用于一些需要保证不同类的一致性但具体实现不同的场景。在实际开发中,需要设计合理的接口,避免不必要的继承和抽象类的使用。
总之,继承、抽象类和接口都是 Java 中重要且基础的概念。深入理解这些概念的含义和使用场景,可以更好地编写出高质量的Java程序。
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号