学生管理系统项目

1学生管理系统项目

实体类: 

 学生类: id, 姓名,年龄,性别,成绩 

 需要使用数组保存学生信息 

 Student[] allStu 需要完成的方法 

 1. 根据学生的ID,找到对应的学生对象【完成】

 2. 完成方法,添加新学生 

 3. 完成方法,删除指定ID的学生 

 4. 完成方法,展示数组中所有的学生信息 

 5. 根据学生成绩,完成降序排

1.1包结构划分

包名规范

1所有的单词全部小写

2不同的单词直接使用,隔开

3包结构其实对应的就是一个真实的目录结构

包结构的使用是为了在开发中让代码更加明确,更好管理,会慢慢接触到MVC设计模式

当前学生管理系统需要的包【目前功能所需】

实体类:

所有实体类都会在一个包下

管理类:

需要一个管理类来管理学生操作【核心】需要一个包

主方法类

主方法

测试类

测试功能,养成习惯,对于代码的功能,写一个测试一个

包名: 

 com.qfedu.student.system 

 --| entity 实体类包 

 --| manager 管理类包 

 --| mainproject 主方法所在包 

 --| testsystem 测试

1.2学生实体类

package com.qfenrxs.student.system.entity;

public class Student {

private int id;

private String name;

private int age;

private char gender;

private int score;

public Student() {

}

public Student(int id, String name, int age, char gender, int score) {

this.id = id;

this.name = name;

this.age = age;

this.gender = gender;

this.score = score;

}

public int getId() {

return id;

}

public void setId(int 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 char getGender() {

return gender;

}

public void setGender(char gender) {

this.gender = gender;

}

public int getScore() {

return score;

}

public void setScore(int score) {

this.score = score;

}

@Override

public String toString() {

return "Student [id = " + id + ", name =" + name + ",age =" + age + ", gender =" + gender + ", score" + score +"]";

}

}

1.3管理功能分析


管理类: 

 1. 数据的保存

 2. 数据处理 CRUD 增删改查 数据的保存 明确使用的是一个Student类型的数据 Student[] allStus; 

 问题:

 成员变量 

 使用一个成员变量数组来保存对应的数据,所有的内 容都依赖于类对象的操作 来完成,而且每一个管理类对象中保存的数据都是不 一样的。 目前的不一样,是为了更好的复用性,后来的数据一 样,是为了数据的统一性 、

静态成员变量 

 不关有多少个类对象,当前数据有且只有一份!!! 复用问题!!!

当前管理类    

功能后期是考虑复用的!!!    不管是数据的存储方式,数据的处理方式,都要需要考虑满足多 种情况,多种方式

1.4管理类构造方法

   因为当前管理类内的成员变量是一个数组,当前构造方法需要对 于保存学生信息的数组进行初始化操作

1. 传入参数是一个学生数组 【不行】 

 2. 传入参数是一个数组容量 √

  传入一个数组,操作性,包括安全性都是存在一定的隐患。操作 性较差,用户需要提供真实管理数据的空间,繁琐,引用指向有可能 导致数据丢失。 传入一个数组容量,用户操作自由度更高!!!方便!!!快 捷!!!省心省事!!!

要求传入的参数是一个数组容量,有没有要求???   

1. int     

2. 非负    

3. int类型的最大值        

【补充】Java中数组容量范围是在int范围以内,要求数 组容量不得超出int范围        Integer.MAX_VALUE - 8、

构造方法这里提供两种    

1. 无参数构造方法        用户不用指定容量,我们给予用户一个初始化容量使用    

2. 有参数构造方法        用户指定底层数组容量,要求数据在合理范围以内

package com.qfenrxs.student.system.manger;

import com.qfenrxs.student.system.entity.Student;

public class StudentManager {

//私有化保存学生信息的数组,对外不公开,有且只针对于当前管理类使用初始化null

private Student[] allStus =null;

//DEFAULT_CAPACITY 默认容量,这里是一个带哟名字的常量

private static final int DEFAULT_CAPACITY = 10;

//数组最大容量是int最大值 -8

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

//当前底层Student数组中有效元素个数

private int size = 0;

public StudentManager() {

allStus = new Student[DEFAULT_CAPACITY];

}

public StudentManager(int initCapacity) {

if (initCapacity < 0 || initCapacity > MAX_ARRAY_SIZE) {

System.out.println("Input Parameter is Invalid!");

System.exit(0);

/* 异常抛出!!! System.exit(0) 退出程序 */

}

allStus = new Student[initCapacity];

}

1.6增删改查方法实现

1.6.1增【重点】

分析: 

 权限修饰符: 

 public √ 

 private 如果私有化,类外无法使用,不能操作数据 是否需要static修饰: 不需要的!!! 保存学生信息的数组是static修饰还是非static修 饰??? 非static修饰 如果当前方法使用static修饰,是没有办法操作类内的成 员变量的!!! 

 返回值类型: 

 boolean       添加成功返回true,添加失败返回false 

 方法名:  

 add   添加

形式参数列表:   

 Student student 

方法声明:

 public boolean add(Student stu)

这里需要采用尾插法数据存入,这里需要一个计数器   

 int类型变量    

局部变量:        

方法运行结束GG思密达,没有了,不存在了,无法保存数 据    

成员变量:       

 可以保证每一个StudentManager对象中存储的内容都是 独立,是根据当前数组中        存储数据的容量来确定   【选择】

 静态成员变量:     

   静态成员变量和类对象无关,而且独此一份,每一个 StudentManager对象中保存        的数据个数都是独立,是不合理的!!

/**

* 当前方法是添加学生类对象到StudentManager中,保存到底层的Student类型数组

*

* @param student Student类对象

* @return 添加成功返回true,失败返回false

*/

public boolean add (Student student) {

/*

* 有效元素个数 size 已经和数组容量一致 Capacity一致

*/

if (size == allStus.length) {

grow(size+1);

// 添加操作是一个元素,最小容量要求就是在原本的数组容量之上 + 1

}

allStus[size] = student;

size += 1;

return true;

}

【重点】

容量不够用怎么办??? 

 扩容!!! 

 数组的容量在创建之后是无法修改的!!! 

 重新创建一个数组!!!

新数组要求比原本的数组容量大。 从原数据数组迁移数据到新数组中 重新赋值成员变量allStus保存的空间地址指向新数组

1.6.2grow方法,底层数组容量扩容方法【核心】


流程  

 1. 获取原数组容量   

 2. 计算得到新数组容量   

 3. 创建新数组   

 4. 迁移数据  

 5. 保存新数组地

方法分析: 

 权限修饰符: 

 public 类外可以随便调用,数组容量不受控制,我们期望的是在数组添加元素时 

 容量不足的情况下,才会调用当前grow方法, public不合适! 【不合适】 

 private 核心操作,主要是在类内使用,类外不能调用 当前方法。√

 是否需要static修饰

因为需要操作类内的底层数组,数组非static修饰,不需 要使用static 

 返回值类型:

 void 当前方法不需要返回值 

 方法名: 

 grow

 形式参数列表: 

 要求最小容量 为了保证add操作在合理的容量范围以内 (MAX_ARRAY_SIZE)操作成功,这里要求 

 通过add方法告知grow方法,最小要求容量扩容到多少? 需要考虑一些极端情况: 

 1. 添加多个,超出了grow增加的范围 

 2. 原数组容量为1,扩容之后不够用 

方法声明: private void grow(int minCapacity);

/**

* 类内私有化方法,用于在添加元素过程中,出现当前底层数组容量不足的情况下 对底层数组进行扩容操作,满足使用要求

*

* @param minCapacity 添加操作要求的最小容量

*/

private void grow(int minCapacity) {

// 1. 获取原数组容量

int oldCapacity = allStus.length;

// 2. 计算得到新数组容量,新数组容量大约是原数组容量的1.5倍

int newCapacity = oldCapacity + oldCapacity /2;

// 3. 判断新数组容量是否满足最小容量要求

if (minCapacity > newCapacity) {

newCapacity =  minCapacity;

}

// 4. 判断当前容量是否超出了MAX_ARRAY_SIZE

if (newCapacity > MAX_ARRAY_SIZE) {

System.exit(0);

}

// 5. 创建新数组

Student[] temp = new Student[newCapacity];

// 6. 数据拷贝

for (int i = 0; i < oldCapacity; i++) {

temp[i] = allStus[i];

}

// 7. 使用allStus保存新数组首地址

allStus = temp;

}

1.6.3删【重点】

方法分析:

 权限修饰符: 

 public √ 

 private 【不合适】 

 是否需要static修饰: 

 不需要 

 返回值类型: 

 boolean 删除成功返回true,删除失败返回false

方法名: 

 remove 移除 

 形式参数列表: 

 int id 

方法声明: 

 public boolean remove(int id)

流程:   

 1. 根据ID找出对应的学生对象在数组中的下标位置   

2. 根据下标位置删除元素,从删除位置开始,之后的元素整体 先前移动    

3. 最后一个原本存在数据的位置赋值为null    

4. size 有效元素个数 -= 1

/**

* 根据用户指定的ID号,删除对应学生类对象

*

* @param id 指定的学生ID好

* @return 删除成功返回true,删除失败返回false

*/

public boolean remove(int id) {

int index = -1;

// 遍历数组的终止条件为size,有效元素个数

for (int i = 0; i < size; i++) {

if (id == allStus[i].getId()) {

index = i;

break;

}

}

/*

* 以上代码循环结束,如果index的值为-1,证明没有找到对应的元素 当前方法无法进行删除操作,返回false

*/

if (-1 == index) {

System.out.println("Not Found!");

return false;

}

/*

* 如果index值不是-1,表示找到了对应需要删除的元素,进行删除操作

*

* 假设原数组容量10,有效元素个数为10,删除下标为5的元素 数组[5] = 数组[6]; 数组[6] = 数组[7]; 数组[7] = 数组[8];

* 数组[8] = 数组[9]; 数组[9] = null;

*

* 数组[i] = 数组[i + 1];

*/

for (int i = index; i < size - 1; i++) {

allStus[i] = allStus[i + 1];

}

// 原本最后一个有效元素位置赋值为null

allStus[size - 1] = null;

// 有效元素个数 - 1

size -= 1;

return true;

}

1.6.4查根据ID得到学生信息【重点】

方法分析: 

 权限修饰符 

 public √ 

 private 

 是否需要static修饰 

 不需要 

 返回值类型: 

 Student学生类对象 

 方法名: 

 get 获取 

 形式参数列表: 

 int id 

方法声明: 

 public Student get(int id)

/**

* 根据指定的ID获取对应的Student类对象

*

* @param id 指定的ID号

* @return 返回对应的Student类对象, 如果没有找到,返回null

*/

public Student get(int id) {

int index = findIndexById(id);

return index > -1 ? allStus[index] : null;

}

1.6.5补充,根据ID获取对应下标位置

方法分析: 

 权限修饰符:

public 

 private √ 给内部其他方法使用的一个功能,不需要对外 

 是否需要static修饰 

 不需要 

 返回值类型: 

 int 需要的是一个下标,为int类型 

 方法名: 

 findIndexById 

 形式参数列表: 

 int id 

方法声明: 

 private int findIndexById(int id)

private int findIndexById(int id) {

int index = -1;

for (int i = 0; i < size; i++) {

if (id == allStus[i].getId()) {

index = i;

break;

}

}

return index;

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。