续简单学生管理系统、包装类--day18

Day18

一、删除的思考题

思考题:删除功能可以省略第一步吗?不可以

有第一步判断学生信息合法性,如果信息不合法会直接结束返回

如果没有第一步,将会在第二步判断是否有该学生query循环匹配查找,数据量大情况,效率很低

二、学生管理系统 --功能实现

StudentManagerSystemImpl类

查询功能

1.根据性别查询学生对象数组

步骤

1.验证学生信息合法性

2.获取符合条件的人数

3.创建新数组

4.遍历数据源,把符合条件的学生对象存入新数组中

@Override
public Student[] getStusByName(String name) {
//1.验证学生信息合法性
if (!StuInfoUtil.isName(name)) {
return null;
}
//2.获取符合条件的人数
int count = 0;
for (int i = 0; i < size; i++) {
if (stus[i].getName().equals(name)) {
count++;
}
}
if (count == 0) {
return null;
}
//3.创建新数组
Student[] newStus = new Student[count];
//4.遍历数据源,把符合条件的学生对象存入新数组中
int index = 0;
for (int i = 0; i < size; i++) {
if (stus[i].getName().equals(name)) {
newStus[index++] = stus[i];
}
}
return newStus;
}

后面几个相似

2.根据性别查询学生对象数组

getStusBySex判断时用“==”,不使用equals无法对基元类型char调用equals(char)

3.根据年龄查询学生对象数组
4.根据班级号查询学生对象数组

queryMenu

main方法中封装前端查询方法(多态)

步骤

  1. 查询功能展示
  2. 声明一个学生数组为空
  3. swicth匹配对应功能
  4. 优化基础办法,提示输入查询条件,学生系统调用相应方法查询,根据条件获取到的学生信息赋值给学生数组(多态)
  5. 对学生数组条件判断,查询成功打印数组(打印数组做成默认方法放在接口中),失败打印错误信息
private static void queryMenu(Scanner scan, StudentManagerSystemImpl sms) {
	System.out.println("请选择查询的条件:");
	System.out.println("1 - 根据姓名查询");
	System.out.println("2 - 根据性别查询");
	System.out.println("3 - 根据年龄查询");
	System.out.println("4 - 根据班级号查询");
	int num = scan.nextInt();
	//第二种
	Student[] stus = null;//2
	switch (num) {
	case 1:
		 System.out.println("请输入需要查询的姓名:");
		 String name = scan.next();//2
		 stus = sms.getStusByName(name);

//第一种最基础的办法
//					 String name = scan.next();//1
//					 Student[] stus = sms.getStusByName(name);
//					 for (Student stu : stus) {
//						System.out.println(stu);
//					}
			break;
		case 2:
			System.out.println("请输入需要查询的性别:");
			char sex  = scan.next().charAt(0);
			stus = sms.getStusBySex(sex);
			break;
		case 3:
			System.out.println("请输入需要查询的起始年龄(包含):");
			int start = scan.nextInt();
			System.out.println("请输入需要查询的结束年龄(不包含):");
			int end = scan.nextInt();
			stus = sms.getStusByAge(start, end);
			break;
		case 4:
			System.out.println("请输入需要查询的班级号:");
			String classId = scan.next();
			stus = sms.getStusByClassId(classId);
			break;
		}
		if (stus != null) {//2
//打印数组做成默认方法
			sms.printStus(stus);
//					for (Student stu : stus) {
//						System.out.println(stu);
//					}
		} else {
			System.out.println("查询错误");
		}
	}

三、包装类

理解:

8种基本数据类型对应类

出现原因:

Java为纯面向对象语言(万物皆对象),8种基本数据类型不能new对象,

就破坏Java为纯面向对象语言的特征,Java为8种基本数据类型分别匹配

了对应的类,这种类叫做包装类/封装类

基本数据类型包装类继承关系
byteByteObject.Number.Byte
shortShortObject.Number.Short
intIntegerObject.Number.Integer
longLongObject.Number.Long
floatFloatObject.Number.Float
doubleDoubleObject.Number.Double
charCharacterObject.Character
booleanBooleanObject.Boolean

注意:

1.int的包装类的写法为:Integer

2.char的包装类的写法为:Charater

3.其余基本数据类型的包装类均是基本类型的首字母大写

装箱和拆箱

手动装箱:

基本数据类型 -> 包装类

int num =100;
Integer integer = Integer.valueOf(num);//静态方法
System.out.println(integer);//String类型的100
手动拆箱:

​ 包装类 -> 基本数据类型

Integer integer = new Integer(100);
int num = integer.intValue();
System.out.println(num);//int类型的100
自动装箱

Window的show View的Navigator查看bin目录的class文件,再反编译查看底层

JDK1.5开始的新特性

基本数据类型 -> 包装类

int num = 100;
Integer integer = num;//底层实现:Integer.valueOf(num);
System.out.println(integer);
自动拆箱

包装类 -> 基本数据类型

Integer integer = new Integer(100);
int num = integer;//底层实现:integer.intValue();
System.out.println(num);

深入Integer的底层原理

面试题

描述下列代码的运行结果

	Integer integer1 = Integer.valueOf(100);
	Integer integer2 = Integer.valueOf(100);
	System.out.println(integer1 == integer2);//引用类型比较内存地址,true
	
	Integer integer3 = Integer.valueOf(200);
	Integer integer4 = Integer.valueOf(200);
	System.out.println(integer3 == integer4);//引用类型比较内存地址,false

面试题:描述Integer的valueOf的底层原理
答:判断输入的int值是否在-127~128的区间内,如果在就从Integer的缓存类数组中获取对象
如果不在,就重新new Integer的对象

MyInteger MyInteger1 = MyInteger.valueOf(100);
MyInteger MyInteger2 = MyInteger.valueOf(100);
System.out.println(MyInteger1 == MyInteger2);//true

MyInteger MyInteger3 = MyInteger.valueOf(200);
MyInteger MyInteger4 = MyInteger.valueOf(200);
System.out.println(MyInteger3 == MyInteger4);//超过范围new对象,false

编写MyInteger

步骤:

  1. 定义一个int变量

  2. 有参构造获值

  3. intValue()返回值

  4. 重写toSting使用valueOf()将int值转换为String字符串再返回

  5. 编写缓存类(静态)

  6. 在缓存类中编写静态代码块初始化缓存数组

public class MyInteger {

  private int value;

  public MyInteger(int value) {
  	super();
  	this.value = value;
  }
  
  public int intValue(){
  	return value;
  }
  //编写MyInteger的valueOf判断输入的int值是否在-127~128的区间内,如果在就从Integer的缓存类数组中获取对象,不在就重新new Integer的对象
  public static MyInteger valueOf(int i){
  	if (i>=MyIntegerCache.low && i<=MyIntegerCache.hight) {
  		return MyIntegerCache.cache[i + (-MyIntegerCache.low)];
  	}
  	return new MyInteger(i);
  }
  
  @Override
  public String toString() {
  	return String.valueOf(value);//将int值转换为String字符串
  }
  
  //缓存类
  private static class MyIntegerCache {//没有用到外部类的成员属性就可制成静态
  	private static final int low = -128;//低位
  	private static final int hight = 127;//高位
  	private static final MyInteger[] cache;//缓存数组(-127~128的MyInteger的对象)
  	
  	static{//可用代码块
  		//初始化缓存数组
  		cache = new MyInteger[hight - low +1];
  		int j = low;
  		for (int i = 0; i < cache.length; i++) {
  			cache[i] = new MyInteger(j++);
  		}
  	}
  }
}

测试

Integer integer = new Integer(100);
	System.out.println(integer);//100
	int num1 = integer.intValue();
	System.out.println(num1);//100
	
	MyInteger myInteger = new MyInteger(100);
	System.out.println(myInteger);
	//直接打印类的全路径com.qf.package_class.MyInteger@15db9742
	//MyInteger中重写toSting方法转化value值之后,100
	int num2 = myInteger.intValue();
System.out.println(nm2);//100

四学生管理系统 --功能实现

StudentManagerSystemImpl类(多态,包装类)

修改功能

注意:

用Object原因:ps:sex自动装箱将char装箱成Character,再将Character向上转型成Object(多态),方法里面又要向下转型

步骤:

  1. 判断学生信息的合法性

  2. 判断是否有该学生

  3. 判断修改类型

  4. switch判断修改类型,对应修改功能

    ​ 优化:利用实现类中定义的静态常量,提高代码可读性(程序定死的可以用)

  5. 对应功能:判断修改的数据的合法性

    ​ 修改数据

@Override
public int update(String classId, String id, int type, Object val) {//用Object原因:ps:sex自动装箱将char装箱成Character,再将Character向上转型成Object(多态),方法里面又要向下转型
	//1.判断学生信息的合法性
	if (!StuInfoUtil.isClassId(classId) && !StuInfoUtil.isId(id)) {
		return -1;
	}
	//2.判断是否有该学生
	int index = query(classId, id);
	if (index == -1) {
		return -2;
	}
	//3.判断修改类型
	switch (type) {

//		利用实现类中定义的静态常量,提高代码可读性(程序定死的可以用)
		case NAME:
			String nameVal = (String)val;
//			外部传进来的val处理,前端可以屏蔽掉
//			if (val instanceof String) {
//				String name = (String)val;
//			}
			//判断修改的数据的合法性
			if (!StuInfoUtil.isName(nameVal)) {
				return -3;
			}
			//修改数据
			stus[index].setName(nameVal);
			break;
		case SEX:
			char sexVal = (Character) val;//强转成Character类型,再自动拆箱成char类型
			//判断修改的数据的合法性
			if (!StuInfoUtil.isSex(sexVal)) {
				return -3;
			}
			//修改数据
			stus[index].setSex(sexVal);
			break;
		case AGE:
			int ageVal = (Integer) val;//强转成Integer类型,再自动拆箱成int类型
			//判断修改的数据的合法性
			if (!StuInfoUtil.isAge(ageVal)) {
				return -3;
			}
			//修改数据
			stus[index].setAge(ageVal);
			break;
		case CLASS_ID:
			String classIdVal = (String)val;
			//判断目标班级上是否有重复学生(即修改班级号对应班级是否已经存在学生 ps:2041 001 -> 2042 001)
			if (query(classIdVal, id) != -1) {
				return -4;
			}
			//判断修改的数据的合法性
			if (!StuInfoUtil.isClassId(classIdVal)) {
				return -3;
			}
			//修改数据
			stus[index].setClassId(classIdVal);
			break;
		case ID:
			String idVal = (String)val;
			//判断目标学号上是否有重复学生(即修改学号对应学号是否已经存在学生 ps:2041 001 -> 2041 002)
			if (query(classId, idVal) != -1) {
				return -5;
			}
			//判断修改的数据的合法性
			if (!StuInfoUtil.isId(idVal)) {
				return -3;
			}
			//修改数据
			stus[index].setId(idVal);
			break;
		}
		return 1;
	}

updateMenu

main方法中封装前端查询方法(多态)

步骤:

  1. 提示输入班级号、学号
  2. 查询功能展示
  3. 声明一个Object为空
  4. swicth匹配对应功能
  5. 优化基础办法,提示输入查询条件,学生系统调用相应方法查询,根据条件获取到的学生信息赋值给Object(多态,向上转型)
  6. 获取修改状态码:学生系统调用添加方法返回修改状态码
  7. 根据修改状态码进行条件判断修改的情况息
private static void updateMenu(Scanner scan, StudentManagerSystemImpl sms) {
	System.out.println("请输入需要修改学生的班级号:");
	String classId = scan.next();
	System.out.println("请输入需要修改学生的学号:");
	String id = scan.next();
	System.out.println("请选择需要修改的类型:");
	System.out.println("1 - 修改姓名");
	System.out.println("2 - 修改性别");
	System.out.println("3 - 修改年龄");
	System.out.println("4 - 修改班级号");
	System.out.println("5 - 修改学号");
	int type = scan.nextInt();
	System.out.println("请输入修改的值");
	Object val = null;
	switch (type) {
	case 1:case 4:case 5:

//					String val = scan.next();
			val = scan.next();//String -> Object
			break;
		case 2:
			val = scan.next().charAt(0);//char -> Character -> Object
			break;
		case 3:
			val = scan.nextInt();//int -> Integer -> Object
			break;
		default:
			System.out.println("修改失败  -- 修改类型错误");
			return;
		}
		int updateCode = sms.update(classId, id, type, val);
		if (updateCode == -1) {
			System.out.println("修改失败 -- 学生信息不合法");
		}else if (updateCode == -2) {
			System.out.println("修改失败 -- 没有该学生");	
		}else if (updateCode == -3) {
			System.out.println("修改失败 -- 修改值的信息不合法");	
		}else if (updateCode == -4) {
			System.out.println("修改失败 -- 目标班级上有学生");	
		}else if (updateCode == -5) {
			System.out.println("修改失败 -- 目标学号上有学生");	
		}else if (updateCode == 1) {
			System.out.println("修改成功");	
		}
	}

总结

1.学生管理系统 – 删除的思考题

2.学生管理系统 – 查询功能

3.包装类
概念
出现原因
手动装箱、手动拆箱
自动装箱、自动拆行
深入Integer的底层原理 – 重要!!!!

4.学生管理系统 – 修改功能

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值