学生管理系统2.0 (可对学生数组扩容)
1.用户可初始化数组长度,不够用时可以扩充数组容量。
尝试完成以下功能
实体类:
学生类:
id, 姓名,年龄,性别,成绩
需要使用数组保存学生信息
Student[] allStu
需要完成的方法
1. 根据学生的ID,找到对应的学生对象【完成】
2. 完成方法,添加新学生
3. 完成方法,删除指定ID的学生
4. 完成方法,展示数组中所有的学生信息
1.1包结构划分
包名规范:
1. 所有的单词全部小写
2. 不同的单词直接使用 . 隔开
3. 包结构其实对应的就是一个真实的目录结构
包结构的使用是为了在开发中让代码结构更加明确,更好管理,会慢慢接触到MVC设计模式。
MVC ==> Model Viewer Controller
目前学生管理系统需要的包【目前功能所需】
实体类 : 所有的实体类都会在一个包下
管理类 : 需要一个管理类来管理学生操作【核心】,需要一个包
主方法类 : 主方法
测试类: 测试功能,养成习惯,对于代码中的功能,写一个测试一个,今天会到用@Test
1.2 学生实体类
package com.wk.entity;
/**
* 学生实体类
* @author Wk
*
*/
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) {
super();
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;
}
/**
* 使用System.out.println打印展示Student类对象时
* 是直接自动调用toString方法,展示该方法返回String字符串内容
*/
@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 为什么-8后面解释!!!
构造方法这里提供两种
1. 无参数构造方法
用户不用指定容量,我们给予用户一个初始化容量使用
2. 有参数构造方法
用户指定底层数组容量,要求数据在合理范围以内
代码如下:
package com.wk.manager;
import com.wk.entity.Student;
public class StudentManager {
/*
* 私有化保存学生信息的数组,对外不公开,只针对本管理类使用
*/
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;
/**
* 无参数构造方法,但是需要创建底层保存学生数据的Student数组,因为当前数组 不存在,指向为null
*
*/
public StudentManager() {
allStus = new Student[DEFAULT_CAPACITY];
}
/**
* 用户指定初始化容量,但是要求初始化容量在合理范围以内,不能小于0 ,不能 大于数组的最大值,MAX_ARRAY_SIZE
*
* @param initCapacity 用户指定的初始化容量
*/
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];
}
/**
* 该方法用于添加学生,将学生信息保存到Student类型数组
* 在数组不够用的情况,需要扩容
*
* @param student Student类对象
* @return 添加成功返回true,失败返回false
*/
public boolean addStudent(Student student) {
//扩容
if(size == allStus.length) {
grow(size + 1);
}
allStus[size] = student;
size+=1;
return true;
}
private void grow(int minCapacity) {
// 1. 获取原数组容量
int oldCapacity = allStus.length;
// 2. 计算得到新数组容量,新数组容量大约是原数组容量的1.5倍
int newCapacity = oldCapacity + oldCapacity / 2;
// 3. 判断新数组容量是否满足最小容量要求(只在原数组容量为1时有用)
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;
}
/**
* 类内私有化方法,用于根据指定ID获取对应的下标位置,提供给其他方法使用
*
* @param id 指定ID号
* @return 返回值是对应的下标位置,返回值大于等于0 表示找到对应元素,返回-1没有找到
*/
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;
}
public void showAllStudents() {
for (int i = 0; i < size; i++) {
System.out.println(allStus[i]);
}
}
/**
* 根据用户指定的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;
}
/**
* 根据指定的ID获取对应的Student类对象
*
* @param id 指定的ID号
* @return 返回对应的Student类对象, 如果没有找到,返回null
*/
public Student get(int id) {
int index = findIndexById(id);
return index > -1 ? allStus[index] : null;
}
}
2.单元测试
package com.wk.test;
import org.junit.Test;
import com.wk.entity.Student;
import com.wk.manager.StudentManager;
public class StudentTest {
@Test
public void test() {
//初始化数组容量为1 不够用会自动扩容
StudentManager stm = new StudentManager(1);
stm.addStudent(new Student(1, "李明", 16, '男', 80));
stm.addStudent(new Student(2, "joker", 16, '男', 70));
stm.addStudent(new Student(3, "wk", 16, '男', 82));
stm.addStudent(new Student(4, "liuliu", 16, '男', 86));
stm.addStudent(new Student(5, "张三", 16, '男', 83));
stm.addStudent(new Student(6, "李四", 16, '男', 81));
stm.addStudent(new Student(7, "王五", 16, '男', 66));
stm.addStudent(new Student(8, "马克", 16, '男', 77));
stm.addStudent(new Student(9, "波罗", 16, '男', 99));
stm.addStudent(new Student(10, "Tony", 16, '男', 100));
stm.addStudent(new Student(11, "屎大颗", 16, '男', 100));
stm.addStudent(new Student(12, "kang", 16, '男', 67));
stm.addStudent(new Student(13, "jiro", 16, '男', 86));
Student student=stm.get(11);
System.out.println(student);
stm.remove(11);
stm.showAllStudents();
}
}