Java- 学生管理系统项目

学生管理系统项目【所有知识点整合】

1.学生管理系统项目
1.1 包结构划分
包名规范:
    1. 所有的单词全部小写
    2. 不同的单词直接使用 . 隔开
    3. 包结构其实对应的就是一个真实的目录结构
包结构的使用是为了在开发中让代码结构更加明确,更好管理,会慢
慢接触到MVC设计模式。
	MVC ==> Model Viewer Controller
目前学生管理系统需要的包【目前功能所需】
    实体类 : 所有的实体类都会在一个包下
    管理类 : 需要一个管理类来管理学生操作【核心】,需要一个包
	主方法类 : 主方法
	测试类: 测试功能,养成习惯,对于代码中的功能,写一个测
试一个,今天会到用@Test


包名:
	com.qfedu.student.system
        --| entity 实体类包
        --| manager 管理类包
        --| mainproject 主方法所在包
        --| testsystem 测试类
1.2 学生实体类
package com.qfedu.student.system.entity;

/**
* 学生实体类
*
* @author Anonymous
*
*/
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. 有参数构造方法
   		用户指定底层数组容量,要求数据在合理范围以内
1.5 构造方法完成和成员变量补充
package com.qfedu.student.system.manager;

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

public class StudentManager {
	
	/**
	* 私有化保存学生信息的数组,对外不能公开,有且只针对于
	当前管理类使用
	* 初始化为null
	*/
	private Student[] allStus = null;
	
	/**
	* DEFAULT_CAPACITY 默认容量,这里是一个带有名字的常量
	*/
	private static final int DEFAULT_CAPACITY = 10;
	
	/**
	* 数组最大容量,是int类型最大值 - 8
	* -8等我给你讲
	*/
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	
	/**
	* 无参数构造方法,但是需要创建底层保存学生数据的
	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 isInvalid!");
			/* 异常抛出!!! 补充该知识点 暂时留下一个
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 stu Student类对象
    * @return 添加成功返回true,失败返回false
    */

public boolean add(Student stu) {
    allStus[size] = stu;
    size += 1;
    return true;
}
目前存在的问题:
    1. 好像没有错误情况处理???
    2. 容量不够用怎么办???
好像没有错误情况处理???
	需要异常处理来辅助完成错误或者说异常处理。
	
容量不够用怎么办???
    扩容!!!
    数组的容量在创建之后是无法修改的!!!
    重新创建一个数组!!!新数组要求比原本的数组容量大。
    从原数据数组迁移数据到新数组中
    重新赋值成员变量allStus保存的空间地址指向新数组
1.6.2 grow方法,底层数组容量扩容方法【核心】
流程
    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);
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)
/**
	 * 类内私有化方法,用于根据指定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]);
		}
	}
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值