JAVA项目-成绩管理系统
成绩管理系统
系统功能:
一个综合的Java项目,可以帮助你练习基本语法、变量、数据类型、运算符以及控制流程,是一个简单的学生成绩管理系统。以下是这个项目的基本要求和功能:
项目名称:学生成绩管理系统
项目功能:
- 学生信息管理:
- 能够添加、编辑和删除学生信息,包括姓名、学号、年龄等。
- 学生信息可以存储在一个数组或集合中。
- 成绩录入:
- 可以为每个学生录入成绩,包括多个科目的分数,如数学、英语、历史等。
- 成绩应与学生信息关联,每个学生可以有多个科目的成绩。
- 成绩统计:
- 能够计算每个学生的总分和平均分。
- 能够计算每个科目的平均分和最高分。
- 成绩排名:
- 能够按照总分或某个特定科目的成绩对学生进行排名。
- 能够显示排名前几名的学生信息和成绩。
- 控制流程:
- 使用if语句来处理特殊情况,例如成绩不合格的学生或需要特殊奖励的学生。
- 使用循环来遍历学生列表,计算总分和平均分,以及进行排名。
- 用户界面:
- 创建一个简单的命令行界面,允许用户执行各种操作,如添加学生、录入成绩、查看排名等。
学习目标和练习点:
- 声明和使用变量来存储学生信息和成绩。
- 使用不同的数据类型来表示学生姓名、学号、年龄和成绩。
- 使用运算符进行数学计算,如加法和除法,以计算总分和平均分。
- 使用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 中,数组的长度一旦创建后是固定的,无法直接改变。如果你需要一个长度可以随意改变的数组,你可以考虑使用集合类,如 ArrayList
。ArrayList
具有动态大小,可以根据需要自动增长或缩小。
以下是如何创建并操作一个长度可以随意改变的 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
或其他类的信息是一项重要的技能。以下是一些具体的步骤,可以帮助你从官方文档中找到相关信息:
- 访问 Java SE API 文档: 首先,前往 Oracle 的 Java SE API 文档网站(https://docs.oracle.com/en/java/)。这是官方的 Java 文档资源。
- 导航到 Java 核心库: 在文档网站上,你可以看到左侧的导航栏,其中有一个 "Java SE" 部分。展开这个部分,你会看到 "Java Platform, Standard Edition" 的链接。点击这个链接。
- 查找 java.util 包: 在 Java SE 文档的导航栏中,你会看到一个 "API" 部分。展开这个部分,然后点击 "java.util" 包的链接。
ArrayList
类位于java.util
包中。 - 查找 ArrayList 类: 在
java.util
包的页面上,你会看到一个包含所有类的列表。在这里,你可以滚动或使用浏览器的搜索功能查找ArrayList
类。点击ArrayList
类的链接,以进入该类的文档页面。 - 查看 ArrayList 文档: 现在你已经进入了
ArrayList
类的文档页面。这里提供了有关该类的详细信息,包括类的继承关系、构造函数、方法、字段等。你可以浏览这些信息,查找你需要的内容。 - 搜索功能: 如果你知道你要查找的特定方法或概念,可以使用页面上的搜索功能。通常,文档页面上会有一个搜索框,你可以在其中输入关键词,然后查找相关信息。
- 示例代码: 在文档中,通常会提供示例代码,以帮助你理解如何使用类和方法。你可以查看示例代码,以获得关于如何使用
ArrayList
的示例。
总之,通过导航官方 Java SE API 文档,你可以找到关于 ArrayList
类和其他 Java 类的详细信息。这个文档资源非常全面,是学习和了解 Java 类库的重要工具。
ArrayList (Java SE 20 & JDK 20) (oracle.com)
代码BUG调试:2023.9.7 1:08
代码看起来基本上没有语法错误,但在 addStudent
和 remove
方法中存在逻辑问题。
-
addStudent 方法问题: 在
addStudent
方法中,你尝试添加一个新的学生到studentArr
中,但使用了一个循环来添加多次。这会导致相同的学生多次添加到列表中。如果你只想要添加一个学生,可以直接使用studentArr.add(newStudent);
,而不需要循环。修复示例:
public static void addStudent(ArrayList<Student> studentArr, Student newStudent) { studentArr.add(newStudent); }
-
remove 方法问题: 在
remove
方法中,你试图通过将匹配的学生设置为null
来删除学生。这种方法会在列表中留下null
值,而不是实际删除学生。你可以考虑使用ArrayList
的remove
方法来删除学生。修复示例:
public static void remove(ArrayList<Student> studentArr, String studentId) { studentArr.removeIf(student -> student != null && student.getStudentId().equals(studentId)); }
以上是你的代码中存在的问题以及如何修复它们的示例。另外,还有一些改进的空间,例如对于 remove
方法,可以考虑使用 HashMap
来更高效地管理学生信息。
实现ArrayList排序算法1:
要实现一个函数,获取 ArrayList
中指定元素的大小排序后的索引,你可以按照以下步骤操作:
- 首先,创建一个新的
ArrayList
来存储原始ArrayList
的索引。 - 遍历原始的
ArrayList
,并将每个元素的索引添加到新的ArrayList
中。 - 使用 Java 的排序方法(如
Collections.sort
)对新的索引列表进行排序,根据元素大小的顺序进行排序。 - 返回排序后的索引列表。
下面是一个示例代码,演示如何实现这个功能:
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.in
和 System.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 # 项目文档
每个文件或目录的含义:
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/
:测试用的资源文件目录。
target/
:Maven 构建生成的编译输出和构建文件所在目录,包括编译后的类文件、JAR 文件等。pom.xml
:Maven 项目的配置文件,定义了项目的依赖、构建插件、目标等信息。README.md
:项目文档,通常包含项目的描述、使用说明和其他有关信息。
这是一个标准的 Maven 项目结构,但根据实际需要,你可以根据项目类型和需求来进行自定义。在 Maven 项目中,主要的 Java 源代码通常位于 src/main/java/
中,主要的资源文件位于 src/main/resources/
中,测试代码位于 src/test/java/
中。项目的依赖和构建配置通常在 pom.xml
文件中定义。