学生管理系统

您所在的位置:网站首页 java编写学生管理系统的设计 学生管理系统

学生管理系统

2024-07-10 00:04| 来源: 网络整理| 查看: 265

今天教大家使用Java编写一个在控制台运行的学生管理系统

学生管理系统,顾名思义就是用来管理学生的一个系统。需要管理的学生较多,因此需要一个适合的数据结构来管理学生的信息。链表简单,适用范围广,因此在这里我们选择使用链表来保存信息。再编写一个管理类整合所有的操作即可。

github仓库:https://github.com/luohao1899/studentsystem.git

一、学生类创建

首先创建一个学生的JavaBean类,类中包含学生的id,姓名,年龄,住址信息。该类用于保存学生的信息,是链表节点的数据域。

public class Student { private String id; private String name; private int age; private String address; public Student(){ } public Student(String id, String name, int age, String address) { this.id = id; this.name = name; this.age = age; this.address = address; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } 二、结点类创建

使用学生类作为结点的数据域。

在结点类中有三个构造方法,空参构造方法,指针参数构造方法,数据域参数构造方法。

结点类包含两个指针:

pre指针:pre指针指向上一个结点。

next指针:next指向下一个结点。

数据域参数构造方法参数为学生类的成员属性,这样设计可以使用户使用时不用创建学生对象就能存储学生信息,学生对象的创建在数据域参数构造方法中自动完成。

指针域为双指针的设计,方便后续的操作。

public Node() { } public Node(Node pre, Node next) { this.pre = pre; this.next = next; } public Node(String id, String name, int age, String address) { this.student = new Student(id,name,age,address); }

对于数据域的get/set方法设计如下。

getStudent方法返回数据域(学生类)的地址,方便对数据域进行一些操作。

setStudent方法传入的参数为数据域的成员属性(id,name,age,address),可以在调用空参构造方法或者指针构造方法的时候对数据域赋值,设计理念同数据域构造方法

public Student getStudent() { return this.student; } public void setStudent(String id, String name, int age, String address) { this.student = new Student(id,name,age,address); }

结点类完整代码如下:

public class Node { private Node pre; private Node next; private Student student; public Node() { } public Node(Node pre, Node next) { this.pre = pre; this.next = next; } public Node(String id, String name, int age, String address) { this.student = new Student(id,name,age,address); } public Node getPre() { return this.pre; } public void setPre(Node pre) { this.pre = pre; } public Node getNext() { return this.next; } public void setNext(Node next) { this.next = next; } public Student getStudent() { return this.student; } public void setStudent(String id, String name, int age, String address) { this.student = new Student(id,name,age,address); } }

 

三、链表设计

学生类和节点类均设计完成,接下来该设计链表了

为了方便理解,我们使用单向循环链表。

链表类的成员属性为:

head:头节点指针,指向链表的头部,构造方法中初始化为一个空的结点。

tail:尾结点指针,指向链表的尾部,构造方法中初始化为指向头节点,后续新节点将从尾部直接插入

length:链表长度,用于存储链表的长度信息

在链表类的成员方法中设计了增、删、查、改四种方法

/** 添加数据 */ public void add(String id, String name, int age, String address) { Node newNode = new Node(id, name, age, address); newNode.setPre(this.tail); this.tail.setNext(newNode); this.tail = newNode; this.length++; } /** 删除数据 */ public void delete(String id) { Node node = this.findNode(id); if(node.getNext() != null){ node.getPre().setNext(node.getNext()); node.getNext().setPre(node.getPre()); this.length--; } } /** 修改数据 */ public void update(String id, String sign, String data) { Node node = this.findNode(id); switch (sign) { case "id" -> node.getStudent().setId(data); case "name" -> node.getStudent().setName(data); case "address" -> node.getStudent().setAddress(data); } } /** 修改数据(age) */ public void update(String id, String sign, int data) { if (sign.equals("age")) { Node node = this.findNode(id); node.getStudent().setAge(data); } } /** 查询数据 */ public String query() { StringBuilder ret = new StringBuilder("id\t\tname\tage\t\taddress\n"); Node node = this.head.getNext(); while (node != null) { ret.append( node.getStudent().getId() ).append( "\t\t" ).append( node.getStudent().getName() ).append( "\t\t" ).append( node.getStudent().getAge() ).append( "\t\t" ).append( node.getStudent().getAddress() ).append( "\n" ); node = node.getNext(); } return ret.toString(); }

修改方法定义了两种,两种方法只有参数表的第三个参数不同:

参数表String id, String sign,String data/int age

id参数传入学生的学号

sign参数传入需要修改的数据的名称,例如:id,name,address,age

第三个参数传入修改后的新的数据,如果是字符串类型自动调用第一种方法,并按照sign参数修改,如果是int类型的参数自动调用第二种方法并比对sign参数是否传入正确,并修改数据

/** 修改数据 */ public void update(String id, String sign, String data) { Node node = this.findNode(id); switch (sign) { case "id" -> node.getStudent().setId(data); case "name" -> node.getStudent().setName(data); case "address" -> node.getStudent().setAddress(data); } } /** 修改数据(age) */ public void update(String id, String sign, int data) { if (sign.equals("age")) { Node node = this.findNode(id); node.getStudent().setAge(data); } }

数据查询方法:

获取所有的数据并整理成字符串并返回

/** 查询数据 */ public String query() { StringBuilder ret = new StringBuilder("id\t\tname\tage\t\taddress\n"); Node node = this.head.getNext(); while (node != null) { ret.append( node.getStudent().getId() ).append( "\t\t" ).append( node.getStudent().getName() ).append( "\t\t" ).append( node.getStudent().getAge() ).append( "\t\t" ).append( node.getStudent().getAddress() ).append( "\n" ); node = node.getNext(); } return ret.toString();

在上述的方法体中还调用的一个名为findNode的方法,该方法用于寻找指定的结点并返回该结点的地址。方法如下:

/** 节点查找 */ private Node findNode(String id) { Node retNode = null; Node node = this.head.getNext(); while (node != null) { if (node.getStudent().getId().equals(id)) { retNode = node; } node = node.getNext(); } return retNode; }

由于这是一个管理学生信息的链表,而学生的id不可重复,因此还需要一个方法用来判断学生的id的唯一性。

在方法内调用findNode方法,如果找到相关结点则findNode返回值不为null,repeat方法返回值为false,表示不重复,否则返回true。

代码如下:

/** id唯一性判断 */ public boolean repeat(String id) { return this.findNode(id) != null; }

在链表中还应该加入一个获取链表的长度的方法,该方法直接返回成员属性length即可。

完整的链表类代码如下:

public class StudentList { private final Node head; private Node tail; private int length; public StudentList() { this.head = new Node(); this.tail = this.head; } /** 添加数据 */ public void add(String id, String name, int age, String address) { Node newNode = new Node(id, name, age, address); newNode.setPre(this.tail); this.tail.setNext(newNode); this.tail = newNode; this.length++; } /** 删除数据 */ public void delete(String id) { Node node = this.findNode(id); if(node.getNext() != null){ node.getPre().setNext(node.getNext()); node.getNext().setPre(node.getPre()); this.length--; } } /** 修改数据 */ public void update(String id, String sign, String data) { Node node = this.findNode(id); switch (sign) { case "id" -> node.getStudent().setId(data); case "name" -> node.getStudent().setName(data); case "address" -> node.getStudent().setAddress(data); } } /** 修改数据(age) */ public void update(String id, String sign, int data) { if (sign.equals("age")) { Node node = this.findNode(id); node.getStudent().setAge(data); } } /** 查询数据 */ public String query() { StringBuilder ret = new StringBuilder("id\t\tname\tage\t\taddress\n"); Node node = this.head.getNext(); while (node != null) { ret.append( node.getStudent().getId() ).append( "\t\t" ).append( node.getStudent().getName() ).append( "\t\t" ).append( node.getStudent().getAge() ).append( "\t\t" ).append( node.getStudent().getAddress() ).append( "\n" ); node = node.getNext(); } return ret.toString(); } /** id唯一性判断 */ public boolean repeat(String id) { boolean ret = false; Node node = this.head.getNext(); while (node != null && !ret) { ret = node.getStudent().getId().equals(id); node = node.getNext(); } return ret; } /** 链表长度 */ public int size() { return this.length; } /** 节点查找 */ private Node findNode(String id) { Node retNode = null; Node node = this.head.getNext(); while (node != null) { if (node.getStudent().getId().equals(id)) { retNode = node; } node = node.getNext(); } return retNode; } }

目前完成了学生类,结点类,链表类的创建,接下来还需要创建一个系统类来方便我们管理

四、管理系统设计

要管理学生信息,首先需要用到链表类,需要创建一个链表类的实例对象。还需要一个Scanner的对象来键盘录入信息

由于创建好实例对象之后不需要修改且外部不能调用,因此直接将该成员属性定义为private final

private final StudentList list; private final Scanner scanner;

添加学生信息的操作如下:

首先录入学生id,若id不重复则依次录入姓名,年龄,住址信息并添加进链表中,提示添加成功,否则返回id重复。

/** 添加学生 */ public void add() { System.out.println("-------添加学生-------"); System.out.println("请输入学生id:"); String id = this.scanner.next(); if (!this.idIsRepeat(id)) { System.out.println("请输入学生姓名:"); String name = this.scanner.next(); System.out.println("请输入学生年龄:"); int age = this.scanner.nextInt(); System.out.println("请输入学生住址:"); String address = this.scanner.next(); this.list.add(id,name,age,address); System.out.println("添加成功!"); } else { System.out.println("id重复!"); } }

删除学生信息的操作如下:

首先录入学生id并判断id是否存在,若id存在则调用链表对象的delete方法删除结点并提示删除成功,否则提示id不存在

/** 删除学生 */ public void delete() { System.out.println("-------删除学生-------"); System.out.println("请输入学生id:"); String id = this.scanner.next(); if (this.idIsRepeat(id)) { this.list.delete(id); System.out.println("删除成功!"); } else { System.out.println("id不存在!"); } }

修改学生信息的操作如下:

同样录入学生id并判断是否存在,并提示录入sign参数。并将id,sign参数传入updateHelp私有方法中,根据sign参数提示输入修改后的数据并与id,sign一同传入链表的update方法完成修改。

/** 修改学生 */ public void update() { System.out.println("-------修改学生-------"); System.out.println("请输入学生id:"); String id = this.scanner.next(); if (this.idIsRepeat(id)) { System.out.println("请输入需要修改的信息类型(id,name,age,address"); String sign = this.scanner.next(); this.updateHelp(id,sign); System.out.println("修改成功!"); } else { System.out.println("id不存在!"); } } /** 修改学生辅助方法 */ private void updateHelp(String id, String sign) { switch (sign) { case "id" -> { System.out.println("请输入新的学生id:"); String newId = this.scanner.next(); this.list.update(id, sign, newId); } case "name" -> { System.out.println("请输入新的学生name:"); String newName = this.scanner.next(); this.list.update(id, sign, newName); } case "age" -> { System.out.println("请输入新的学生age:"); int newAge = this.scanner.nextInt(); this.list.update(id, sign, newAge); } case "address" -> { System.out.println("请输入新的学生address:"); String newAddress = this.scanner.next(); this.list.update(id, sign, newAddress); } } }

查询学生信息的方法如下:

判断链表是否为空,不为空则调用链表的query方法获取包含所有信息的字符串并打印该字符串。

/** 查询学生 */ public void query() { System.out.println("-------查询学生-------"); if (this.list.size() > 0) { System.out.println(this.list.query()); } }

在管理类中还有一个判断id是否重复的方法,该方法其实是链表的repeat方法的套壳。

编写该方法的目的是为了增加代码的可读性,避免在管理类中多次调用链表类的方法。

/** id是否重复 */ private boolean idIsRepeat(String id){ return this.list.repeat(id); }

还需要定义一个方法用来整理好所有的操作,以此来方便操作。

输出相关提示并键盘录入用户的操作并调用相关方法执行该操作即可

/** 运行方法 */ public void run(){ loop:while (true) { System.out.println("-----学生管理系统-----"); System.out.println("\t1:添加学生"); System.out.println("\t2:删除学生"); System.out.println("\t3:修改学生"); System.out.println("\t4:查询学生"); System.out.println("\t5:退出系统"); System.out.println("请输入您想操作的选项标号:"); String choose = this.scanner.next(); switch (choose){ case "1" -> this.add(); case "2" ->this. delete(); case "3" -> this.update(); case "4" -> this.query(); case "5" -> { System.out.println("感谢使用本系统!"); break loop; } default -> System.out.println("没有这个选项"); } } }

完整的管理类代码如下:

import java.util.Scanner; public class StudentSystem { private final StudentList list; private final Scanner scanner; public StudentSystem() { this.list = new StudentList(); this.scanner = new Scanner(System.in); } /** 添加学生 */ public void add() { System.out.println("-------添加学生-------"); System.out.println("请输入学生id:"); String id = this.scanner.next(); if (!this.idIsRepeat(id)) { System.out.println("请输入学生姓名:"); String name = this.scanner.next(); System.out.println("请输入学生年龄:"); int age = this.scanner.nextInt(); System.out.println("请输入学生住址:"); String address = this.scanner.next(); this.list.add(id,name,age,address); System.out.println("添加成功!"); } else { System.out.println("id重复!"); } } /** 删除学生 */ public void delete() { System.out.println("-------删除学生-------"); System.out.println("请输入学生id:"); String id = this.scanner.next(); if (this.idIsRepeat(id)) { this.list.delete(id); System.out.println("删除成功!"); } else { System.out.println("id不存在!"); } } /** 修改学生 */ public void update() { System.out.println("-------修改学生-------"); System.out.println("请输入学生id:"); String id = this.scanner.next(); if (this.idIsRepeat(id)) { System.out.println("请输入需要修改的信息类型(id,name,age,address"); String sign = this.scanner.next(); this.updateHelp(id,sign); System.out.println("修改成功!"); } else { System.out.println("id不存在!"); } } /** 查询学生 */ public void query() { System.out.println("-------查询学生-------"); if (this.list.size() > 0) { System.out.println(this.list.query()); } } /** 菜单方法 */ public void run(){ loop:while (true) { System.out.println("-----学生管理系统-----"); System.out.println("\t1:添加学生"); System.out.println("\t2:删除学生"); System.out.println("\t3:修改学生"); System.out.println("\t4:查询学生"); System.out.println("\t5:退出系统"); System.out.println("请输入您想操作的选项标号:"); String choose = this.scanner.next(); switch (choose){ case "1" -> this.add(); case "2" ->this. delete(); case "3" -> this.update(); case "4" -> this.query(); case "5" -> { System.out.println("感谢使用本系统!"); break loop; } default -> System.out.println("没有这个选项"); } } } /** 修改学生辅助方法 */ private void updateHelp(String id, String sign) { switch (sign) { case "id" -> { System.out.println("请输入新的学生id:"); String newId = this.scanner.next(); this.list.update(id, sign, newId); } case "name" -> { System.out.println("请输入新的学生name:"); String newName = this.scanner.next(); this.list.update(id, sign, newName); } case "age" -> { System.out.println("请输入新的学生age:"); int newAge = this.scanner.nextInt(); this.list.update(id, sign, newAge); } case "address" -> { System.out.println("请输入新的学生address:"); String newAddress = this.scanner.next(); this.list.update(id, sign, newAddress); } } } /** id是否重复 */ private boolean idIsRepeat(String id){ return this.list.repeat(id); } }

所有代码均完成,接下来在测试类中可以运行以下!

五、测试

创建测试类,创建管理系统的实例对象,并运行管理系统的run方法,在控制台输入相关操作完成测试。

测试类代码如下:

public class Main { public static void main(String[] args) { StudentSystem system = new StudentSystem(); system.run(); } }

运行,并在控制台进行相关操作即可。

以上为学生管理系统的详细介绍及代码展示



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3