JAVA项目-成绩管理系统

发布时间 2023-09-07 02:34:47作者: aondw

成绩管理系统

系统功能:

一个综合的Java项目,可以帮助你练习基本语法、变量、数据类型、运算符以及控制流程,是一个简单的学生成绩管理系统。以下是这个项目的基本要求和功能:

项目名称:学生成绩管理系统

项目功能:

  1. 学生信息管理
    • 能够添加、编辑和删除学生信息,包括姓名、学号、年龄等。
    • 学生信息可以存储在一个数组或集合中。
  2. 成绩录入
    • 可以为每个学生录入成绩,包括多个科目的分数,如数学、英语、历史等。
    • 成绩应与学生信息关联,每个学生可以有多个科目的成绩。
  3. 成绩统计
    • 能够计算每个学生的总分和平均分。
    • 能够计算每个科目的平均分和最高分。
  4. 成绩排名
    • 能够按照总分或某个特定科目的成绩对学生进行排名。
    • 能够显示排名前几名的学生信息和成绩。
  5. 控制流程
    • 使用if语句来处理特殊情况,例如成绩不合格的学生或需要特殊奖励的学生。
    • 使用循环来遍历学生列表,计算总分和平均分,以及进行排名。
  6. 用户界面
    • 创建一个简单的命令行界面,允许用户执行各种操作,如添加学生、录入成绩、查看排名等。

学习目标和练习点:

  • 声明和使用变量来存储学生信息和成绩。
  • 使用不同的数据类型来表示学生姓名、学号、年龄和成绩。
  • 使用运算符进行数学计算,如加法和除法,以计算总分和平均分。
  • 使用if语句来处理条件逻辑,例如判断成绩是否合格。
  • 使用for或while循环来遍历学生列表并执行操作,例如计算总分和排名。
  • 创建函数或方法来组织代码,以便提高可维护性。
  • 学习如何从命令行接受用户输入,以及如何在命令行显示输出。

通过实现这个项目,你将有机会应用Java的基本语法和控制流程,同时构建一个有用的小型应用程序,用于学生成绩管理。这个项目可以逐步扩展和改进,以进一步提高你的编程技能。

code:

com.learn.mains.java

package com.learn;

import com.learn.Student;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

public class week1 {

    public static void addStudent(ArrayList<Student> studentArr,Student newStudent) {
        studentArr.add(newStudent);
    }

    public static void remove(ArrayList<Student> studentArr, String studentId) {
        studentArr.removeIf(student -> student != null && student.getStudentId().equals(studentId));
    }

    public static int getTotalScore(ArrayList<Student> studentArr){
        int sums = 0;
        for(Student student : studentArr){
            if(student!=null)sums += student.getScore();
        }
        return sums;
    }

    public static int getStudentNums(ArrayList<Student> studentArr){
        int lens = 0;
        for(Student student : studentArr){
            if(student != null){
                lens++;
            }
        }
        return lens;
    }

    public static int getAverage(ArrayList<Student> studentArr){
        int allScore =getTotalScore(studentArr);
        int nums =getStudentNums(studentArr);
        if(nums == 0){
            return 0;
        }
        return allScore/nums;
    }

    public static boolean isPassGrade(int goal){
        if(goal >= 60)return true;
        else return false;
    }

    public static void computeRank(ArrayList<Student> studentArr){
        // 使用 Collections.sort 对索引进行排序,根据元素大小的顺序
        Collections.sort(studentArr, new Comparator<Student>() {
            @Override
            public int compare(Student index1, Student index2) {
                return Integer.compare(index2.getScore(), index1.getScore());
            }
        });

        for(int i = 0; i < studentArr.size(); i++){
            System.out.println("rank:" + (i + 1) + " ==> " + studentArr.get(i));
        }
    }

    public static void main(String[] args) {
        ArrayList<Student> studentArr = new ArrayList<>();

addStudent(studentArr,new Student("Alice","001",20,10));
addStudent(studentArr,new Student("Bob","002",21,80));
addStudent(studentArr,new Student("Jerry","003",24,77));

//        for(Student i:studentArr){
//            if(i!=null){
//                System.out.println(i);
//            }
//        }

//        System.out.println("平均成绩为:" + getAverage(studentArr));
//        System.out.println("总成绩为:" + getTotalScore(studentArr));
        System.out.println("=================当前的学生排名现状=================");
computeRank(studentArr);

        Scanner scanner = new Scanner(System.in);

        while(true){
            System.out.println("请选择进行的操作:");
            System.out.println("1.添加学生信息");
            System.out.println("2.删除指定Id的学生");
            System.out.println("3.查看当前排名情况");
            System.out.println("4.退出系统");
            System.out.print(">> Please input 1/2/3/4\n>> ");

            int choise = scanner.nextInt();
            scanner.nextLine();

            switch (choise){
                case 1:
                    System.out.println("请输入学生姓名:");
                    String name = scanner.nextLine();
                    System.out.println("请输入学生Id:");
                    String studentId = scanner.nextLine();
                    System.out.println("请输入学生年龄:");
                    int age = scanner.nextInt();
                    System.out.println("请输入学生成绩:");
                    int score = scanner.nextInt();

addStudent(studentArr,new Student(name,studentId,age,score));
                    System.out.println("==================录入学生成绩成功!==================");
                    break;

                case 2:
                    System.out.println("请输入要删除的学生Id:");
                    String studentIdDe = scanner.nextLine();
remove(studentArr,studentIdDe);
                    System.out.println("==================删除学生信息成功!==================");
                    break;

                case 3:
computeRank(studentArr);
                    break;

                case 4:
                    System.out.println("==================感谢使用!再见!==================");
                    System.exit(0);
                    break;

                default:
                    System.out.println("==================无效的操作!请重新输入!==================");
            }
        }
    }
}

com.learn.Student.java

package com.learn;

public class Student{
    private String name;
    private String studentId;
    private int age;
    private int score;

    public Student(String name,String studentId,int age, int score){
        this.name=name;
        this.studentId=studentId;
        this.age=age;
        this.score=score;
    }

    public String getName(){
        return name;
    }

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

    public String getStudentId(){
        return studentId;
    }

    public void setStudentId(String studentId){
        this.studentId=studentId;
    }

    public int getAge(){
        return age;
    }

    public void setAge(int age){
        this.age=age;
    }

    public int getScore(){
        return score;
    }

    public void setScore(int score){
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{name='"+name+"',studentId='"+studentId+"',age=" + age + ",score='" + score + "'}";
    }
}

可以变长的数组创建:

在 Java 中,数组的长度一旦创建后是固定的,无法直接改变。如果你需要一个长度可以随意改变的数组,你可以考虑使用集合类,如 ArrayListArrayList 具有动态大小,可以根据需要自动增长或缩小。

以下是如何创建并操作一个长度可以随意改变的 ArrayList

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        // 创建一个 ArrayList,初始容量为10(可根据需要调整)
        ArrayList<Student> studentList = new ArrayList<>();

        // 添加元素
        Student student1 = new Student("Alice", 1);
        Student student2 = new Student("Bob", 2);

        studentList.add(student1);
        studentList.add(student2);

        // 获取元素
        Student firstStudent = studentList.get(0);
        System.out.println("First Student: " + firstStudent.getName());

        // 修改元素
        Student updatedStudent = new Student("Charlie", 3);
        studentList.set(0, updatedStudent);

        // 删除元素
        studentList.remove(1);

        // 获取列表大小
        int size = studentList.size();
        System.out.println("Number of Students: " + size);
    }
}

在上面的示例中,我们使用 ArrayList 创建了一个长度可以随意改变的列表,可以动态添加、修改和删除元素。这使得 ArrayList 成为一种灵活的数据结构,适用于需要经常改变大小的情况。

变长数组传参方法:

要将 ArrayList(例如 studentList)传递给其他函数,你只需要将它作为函数的参数传递即可。以下是一个示例,展示如何将 studentList 传递给另一个函数:

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Student> studentList = new ArrayList<>();

        // 添加一些学生到列表
        Student student1 = new Student("Alice", 1);
        Student student2 = new Student("Bob", 2);
        studentList.add(student1);
        studentList.add(student2);

        // 调用另一个函数并传递 studentList 作为参数
        processStudentList(studentList);
    }

    // 另一个函数,接受 ArrayList<Student> 作为参数
    public static void processStudentList(ArrayList<Student> students) {
        // 在这里可以使用 students 参数来操作学生列表
        // 例如,遍历学生列表并执行一些操作
        for (Student student : students) {
            System.out.println("Name: " + student.getName() + ", ID: " + student.getId());
        }
    }
}

在上面的示例中,我们创建了一个名为 processStudentList 的函数,并将 studentList 作为参数传递给该函数。在 processStudentList 函数内部,我们可以使用传递进来的 students 参数来访问和操作学生列表。这样,你可以在不同的函数之间共享和操作 ArrayList

文档查询方法

从官方 Java 文档中查找 ArrayList 或其他类的信息是一项重要的技能。以下是一些具体的步骤,可以帮助你从官方文档中找到相关信息:

  1. 访问 Java SE API 文档: 首先,前往 Oracle 的 Java SE API 文档网站(https://docs.oracle.com/en/java/)。这是官方的 Java 文档资源。
  2. 导航到 Java 核心库: 在文档网站上,你可以看到左侧的导航栏,其中有一个 "Java SE" 部分。展开这个部分,你会看到 "Java Platform, Standard Edition" 的链接。点击这个链接。
  3. 查找 java.util 包: 在 Java SE 文档的导航栏中,你会看到一个 "API" 部分。展开这个部分,然后点击 "java.util" 包的链接。ArrayList 类位于 java.util 包中。
  4. 查找 ArrayList 类:java.util 包的页面上,你会看到一个包含所有类的列表。在这里,你可以滚动或使用浏览器的搜索功能查找 ArrayList 类。点击 ArrayList 类的链接,以进入该类的文档页面。
  5. 查看 ArrayList 文档: 现在你已经进入了 ArrayList 类的文档页面。这里提供了有关该类的详细信息,包括类的继承关系、构造函数、方法、字段等。你可以浏览这些信息,查找你需要的内容。
  6. 搜索功能: 如果你知道你要查找的特定方法或概念,可以使用页面上的搜索功能。通常,文档页面上会有一个搜索框,你可以在其中输入关键词,然后查找相关信息。
  7. 示例代码: 在文档中,通常会提供示例代码,以帮助你理解如何使用类和方法。你可以查看示例代码,以获得关于如何使用 ArrayList 的示例。

总之,通过导航官方 Java SE API 文档,你可以找到关于 ArrayList 类和其他 Java 类的详细信息。这个文档资源非常全面,是学习和了解 Java 类库的重要工具。

ArrayList (Java SE 20 & JDK 20) (oracle.com)

代码BUG调试:2023.9.7 1:08

代码看起来基本上没有语法错误,但在 addStudentremove 方法中存在逻辑问题。

  1. addStudent 方法问题:addStudent 方法中,你尝试添加一个新的学生到 studentArr 中,但使用了一个循环来添加多次。这会导致相同的学生多次添加到列表中。如果你只想要添加一个学生,可以直接使用 studentArr.add(newStudent);,而不需要循环。

    修复示例:

    public static void addStudent(ArrayList<Student> studentArr, Student newStudent) {
        studentArr.add(newStudent);
    }
    
    
  2. remove 方法问题:remove 方法中,你试图通过将匹配的学生设置为 null 来删除学生。这种方法会在列表中留下 null 值,而不是实际删除学生。你可以考虑使用 ArrayListremove 方法来删除学生。

    修复示例:

    public static void remove(ArrayList<Student> studentArr, String studentId) {
        studentArr.removeIf(student -> student != null && student.getStudentId().equals(studentId));
    }
    
    

以上是你的代码中存在的问题以及如何修复它们的示例。另外,还有一些改进的空间,例如对于 remove 方法,可以考虑使用 HashMap 来更高效地管理学生信息。

实现ArrayList排序算法1:

要实现一个函数,获取 ArrayList 中指定元素的大小排序后的索引,你可以按照以下步骤操作:

  1. 首先,创建一个新的 ArrayList 来存储原始 ArrayList 的索引。
  2. 遍历原始的 ArrayList,并将每个元素的索引添加到新的 ArrayList 中。
  3. 使用 Java 的排序方法(如 Collections.sort)对新的索引列表进行排序,根据元素大小的顺序进行排序。
  4. 返回排序后的索引列表。

下面是一个示例代码,演示如何实现这个功能:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static List<Integer> getSortedIndices(ArrayList<Integer> list, int element) {
        // 创建一个新的 ArrayList 来存储索引
        List<Integer> indices = new ArrayList<>();

        // 遍历原始 ArrayList 并记录索引
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == element) {
                indices.add(i);
            }
        }

        // 使用 Collections.sort 对索引进行排序,根据元素大小的顺序
        Collections.sort(indices, new Comparator<Integer>() {
            @Override
            public int compare(Integer index1, Integer index2) {
                return Integer.compare(list.get(index1), list.get(index2));
            }
        });

        return indices;
    }

    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(2);
        numbers.add(7);
        numbers.add(2);
        numbers.add(8);
        numbers.add(2);

        int elementToFind = 2;
        List<Integer> sortedIndices = getSortedIndices(numbers, elementToFind);

        System.out.println("元素 " + elementToFind + " 的索引按大小排序为:" + sortedIndices);
    }
}

在上述示例中,getSortedIndices 函数接受一个 ArrayList 和要查找的元素,然后返回指定元素的大小排序后的索引列表。注意,如果有多个相同的元素,它们的索引会按大小顺序排列。

ArrayList排序:

如果你不希望更改元素类型并且仍然希望使用 ArrayList,但每次添加元素时进行自动排序,你可以在添加元素之后手动调用排序函数,例如 Collections.sort。以下是如何实现这一点:

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();

        // 添加元素
        numbers.add(5);
        numbers.add(2);
        numbers.add(7);
        numbers.add(2);
        numbers.add(8);
        numbers.add(2);

        // 手动排序
        Collections.sort(numbers);

        // 获取有序元素
        for (int element : numbers) {
            System.out.println(element);
        }
    }
}

在上述示例中,我们首先使用 ArrayList 添加元素,然后使用 Collections.sort 对列表进行手动排序。这会将列表中的元素按升序排序。之后,你可以遍历列表并访问已排序的元素。

这种方式确保了元素在添加后进行排序,但需要注意的是,每次添加新元素后都要手动调用排序函数,这可能会导致性能开销。如果需要频繁添加元素,并且要求在每次添加后都进行排序,考虑使用其他自动排序的数据结构,如 TreeSet

collections.sort用于排序一个结构体类的ArrayList:

代码几乎正确,但有一个小错误,你应该使用 Integer 类型的索引进行比较,而不是 studentArr 中的元素。因为 Collections.sort 期望你提供一个比较器来比较元素本身,而不是元素的索引。这里是修复后的代码:

Collections.sort(studentArr, new Comparator<Student>() {
    @Override
    public int compare(Student student1, Student student2) {
        return Integer.compare(student1.getScore(), student2.getScore());
    }
});

上述代码中,我们使用 Comparator 来比较 Student 对象的分数属性,而不是索引。这样可以确保 studentArr 中的学生对象按照分数进行排序。

你的比较器的目标是对 Student 对象进行比较,因此应该接受 Student 类型而不是 Integer 类型的参数。

collections.sort实现逆序

要使用 Collections.sort 对列表进行逆序排序,你可以传递一个自定义的比较器(Comparator)来指定逆序排序的规则。以下是如何实现逆序排序的示例:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(2);
        numbers.add(7);
        numbers.add(2);
        numbers.add(8);
        numbers.add(2);

        // 自定义逆序比较器
        Comparator<Integer> reverseComparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer num1, Integer num2) {
                // 逆序比较,通过交换 num1 和 num2 的位置来实现逆序
                return Integer.compare(num2, num1);
            }
        };

        // 使用逆序比较器进行排序
        Collections.sort(numbers, reverseComparator);

        // 获取逆序排列的元素
        for (int element : numbers) {
            System.out.println(element);
        }
    }
}

在上述示例中,我们首先创建了一个自定义的逆序比较器 reverseComparator,它通过交换比较的元素来实现逆序比较。然后,我们使用 Collections.sort 方法并传递这个逆序比较器来对列表进行逆序排序。

这样,你可以确保列表中的元素按照逆序排列。如果要对其他类型的对象进行逆序排序,只需根据对象的属性或条件修改比较器即可。

基本的控制台交互代码编写:

要创建一个简单的命令行界面,允许用户执行各种操作,你可以使用 Java 的标准输入和输出(System.inSystem.out)来与用户进行交互。以下是一个简单的示例,演示如何创建一个基本的命令行界面来添加学生、录入成绩、查看排名等操作:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

public class CommandLineApp {
    public static void main(String[] args) {
        ArrayList<Student> studentList = new ArrayList<>();
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("\\n请选择操作:");
            System.out.println("1. 添加学生");
            System.out.println("2. 录入成绩");
            System.out.println("3. 查看排名");
            System.out.println("4. 退出");
            System.out.print("请输入操作编号: ");

            int choice = scanner.nextInt();
            scanner.nextLine(); // 消耗换行符

            switch (choice) {
                case 1:
                    System.out.print("请输入学生姓名: ");
                    String name = scanner.nextLine();
                    System.out.print("请输入学号: ");
                    String studentId = scanner.nextLine();
                    studentList.add(new Student(name, studentId, 0));
                    System.out.println("学生添加成功!");
                    break;
                case 2:
                    System.out.print("请输入学号: ");
                    String id = scanner.nextLine();
                    System.out.print("请输入成绩: ");
                    int score = scanner.nextInt();
                    scanner.nextLine(); // 消耗换行符

                    // 查找学生并录入成绩
                    for (Student student : studentList) {
                        if (student.getStudentId().equals(id)) {
                            student.setScore(score);
                            System.out.println("成绩录入成功!");
                            break;
                        }
                    }
                    break;
                case 3:
                    // 使用自定义比较器对学生列表排序
                    Collections.sort(studentList, new Comparator<Student>() {
                        @Override
                        public int compare(Student student1, Student student2) {
                            return Integer.compare(student2.getScore(), student1.getScore());
                        }
                    });

                    // 打印排名
                    System.out.println("\\n学生成绩排名:");
                    for (int i = 0; i < studentList.size(); i++) {
                        Student student = studentList.get(i);
                        System.out.println("排名:" + (i + 1) + ",姓名:" + student.getName() + ",学号:" + student.getStudentId() + ",成绩:" + student.getScore());
                    }
                    break;
                case 4:
                    System.out.println("感谢使用,再见!");
                    System.exit(0);
                default:
                    System.out.println("无效的操作,请重新输入。");
            }
        }
    }
}

在上述示例中,我们使用 Scanner 对象从标准输入读取用户输入,然后根据用户的选择执行相应的操作。用户可以选择添加学生信息、录入成绩、查看排名或退出程序。学生信息存储在 studentList 中,并根据成绩进行排名。

请根据你的需求扩展和修改这个示例,以适应你的具体应用场景和操作。此示例只是一个基本的框架,可以作为起点来构建更复杂的命令行应用。

scanner读入int类型:

通过 Scanner 读取整数数据非常简单。你可以使用 nextInt() 方法从标准输入读取整数。以下是一个示例:

import java.util.Scanner;

public class ReadIntExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入一个整数: ");
        int num = scanner.nextInt();

        System.out.println("你输入的整数是: " + num);

        // 记得关闭 Scanner
        scanner.close();
    }
}

在上述示例中,我们创建了一个 Scanner 对象 scanner,然后使用 nextInt() 方法从标准输入读取整数并将其存储在变量 num 中。最后,我们打印出用户输入的整数。

记得在程序结束时关闭 Scanner 对象,以避免资源泄漏。在实际应用中,你可能需要处理异常情况,例如用户输入的不是整数。

输出改变颜色:

在标准Java中,System.out.println() 输出的文本颜色不能直接更改,因为它是控制台的默认颜色。不过,你可以使用一些特殊字符来实现一些基本的文本效果,例如使用 ANSI 转义序列来改变文本颜色。

请注意,不同的操作系统和控制台可能对 ANSI 转义序列的支持不同。以下是一个在支持 ANSI 转义序列的终端上将文本颜色更改为红色的示例:

public class RedTextExample {
    public static void main(String[] args) {
        // ANSI 转义序列,将文本颜色设置为红色
        System.out.println("\\u001B[31mThis text is red.");

        // 恢复默认文本颜色
        System.out.println("\\u001B[0mThis text is back to the default color.");
    }
}

在上述示例中,我们使用 ANSI 转义序列 \\u001B[31m 来将文本颜色设置为红色。然后,使用 \\u001B[0m 恢复默认文本颜色。

请注意,这种方法依赖于终端的支持,不同的终端可能需要不同的转义序列。在一些IDE中,也可以找到插件或设置来改变控制台文本的颜色,但这通常是IDE特定的功能。

maven介绍

Maven 项目的基本结构通常遵循一定的约定,这样 Maven 能够正确地构建和管理项目。下面是一个标准的 Maven 项目结构示例,以及每个文件或目录的含义:

my-maven-project/
├── src/
│   ├── main/
│   │   ├── java/          # 主要的 Java 源代码
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── MyApp.java
│   │   ├── resources/     # 主要的资源文件,如配置文件
│   │   └── webapp/        # Web 应用程序的根目录(如果是 Web 项目)
│   │
│   ├── test/
│   │   ├── java/          # 测试用的 Java 源代码
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── MyAppTest.java
│   │   └── resources/     # 测试用的资源文件
│   │
├── target/                # 生成的编译输出和构建文件
├── pom.xml                # Maven 项目配置文件
└── README.md              # 项目文档

每个文件或目录的含义:

  1. src/:源代码和资源文件的根目录。
    • src/main/:主要源代码和资源文件的根目录。
      • src/main/java/:主要的 Java 源代码目录。
      • src/main/resources/:主要的资源文件目录,如配置文件。
      • src/main/webapp/:如果项目是一个 Web 应用程序,这是 Web 应用程序的根目录,包含了网页文件、CSS、JavaScript 等。
    • src/test/:测试用源代码和资源文件的根目录,用于单元测试和集成测试。
      • src/test/java/:测试用的 Java 源代码目录。
      • src/test/resources/:测试用的资源文件目录。
  2. target/:Maven 构建生成的编译输出和构建文件所在目录,包括编译后的类文件、JAR 文件等。
  3. pom.xml:Maven 项目的配置文件,定义了项目的依赖、构建插件、目标等信息。
  4. README.md:项目文档,通常包含项目的描述、使用说明和其他有关信息。

这是一个标准的 Maven 项目结构,但根据实际需要,你可以根据项目类型和需求来进行自定义。在 Maven 项目中,主要的 Java 源代码通常位于 src/main/java/ 中,主要的资源文件位于 src/main/resources/ 中,测试代码位于 src/test/java/ 中。项目的依赖和构建配置通常在 pom.xml 文件中定义。