1 需求分析
大学生考勤是治理工作的重要内容,同时也是学校治理的重要组成部分,通过和指导老师交流,了解到本系统中的数据源于标准输入设备(如键盘),或者来自某文件,可以实现对大学生考勤信息的添加,根据需要也可查询用户所需的学生考勤信息、删除无价值的信息、修改错误的信息等,总之本系统,要具备如下功能:添加信息、查询信息、删除信息、修改信息、将信息排序、显示所有信息、数据统计、退出和保存信息,能够通过本系统便利的实现对学生考勤情况的把控,要求操作界面友好,便捷,有一定的容错率。
2 概要设计
- 数据组织
使用集合临时存储每个学生信息和考勤情况,利用文件存储,达到对学生信息的永久记录。定义add()函数添加学生信息,定义find()函数查找学生信息,定义change()函数修改学生信息,定义Delete()函数删除学生信息,定义Print()函数打印学生信息,定义Data()函数打印所需资料表,定义paixv()函数实现用学号对学生进行排序。
2.功能模块
需要实现的功能:
(1)新增学生信息数据。
(2)数据的查找。
(3)学生记录的修改。
(4)学生记录的删除。
(5)显示学生考勤数据列表。
(6)对数据进行排序。
(7)数据统计。
(8)保存数据到文件中并从文件中读入数据。
3 运行环境(软、硬件环境)
1.硬件环境:PC机-内存 16GB。
2.软件环境:操作系统-windows10。
4 开发工具和编程语言
开发环境:eclipse。
编程语言:Java。
5 详细设计
本系统实现了新增学生信息数据、数据的查找、学生记录的修改、学生记录的删除、显示学生考勤数据列表、学生信息排序、数据统计。具体展示如下:
5.1 新增学生数据
新增学生数据功能需要输入学生的学号,如果学号已存在,显示此人已存在。如果学号不存在,输入学生姓名、班级、考勤日期和考勤结果。具体代码如下所示:
public static void add(String fileName) throws IOException{
Scanner in = new Scanner(System.in);
//创建集合对象
ArrayList<Students> array = new ArrayList<Students>();
//从文件中读取学生信息到集合中
readFile(fileName,array);
System.out.println("请输入学生的学号:");
String studentID=in.nextLine();
boolean flag=false;
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getstudentID().equals(studentID))
{
flag=true;
System.out.println("此人已存在");
break;
}
}
if(flag==false)
{
System.out.println("请输入学生姓名:");
String name=in.nextLine();
System.out.println("请输入学生班级:");
String classNumber=in.nextLine();
System.out.println("请输入学生考勤日期:");
String date=in.nextLine();
System.out.println("请输入学生的考勤结果:出 勤 √ 旷 课 X 事 假 ▲ 病 假 ● 迟 到 + 早 退 –");
String result=in.nextLine();
Students s=new Students();
s.setstudentID(studentID);
s.setclassNumber(classNumber);
s.setname(name);
s.setdate(date);
s.setresult(result);
array.add(s);
//把集合中学生信息写到文件中
writeFile(fileName,array);
System.out.println("添加成功!");
System.out.println("添加成功!按回车键返回!");
in.nextLine();
}
}
5.2 查找学生数据
查找学生数据功能,选择按学号查找或按姓名查找,输入学号或姓名。如果存在此学生,打印学生信息。如果不存在此学生,显示不存在此信息。具体代码如下所示:
public static void find(String fileName) throws IOException{
//创建集合对象
ArrayList<Students> array = new ArrayList<Students>();
//从文件中读取学生信息到集合中
readFile(fileName,array);
Scanner in = new Scanner(System.in);
int flag=-1,x,i,t;
String name;String studentID;
System.out.println("<1>按学号查找");
System.out.println("<2>按姓名查找");
x=in.nextInt();
in.nextLine();
if(x==1)
{
flag=-1;
System.out.println("请输入该生学号:");
studentID=in.nextLine();
for(i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getstudentID().equals(studentID))
{
flag=1;
System.out.println("学号"+"\t"+"\t"+"姓名"+"\t"+"班级"+"\t"+"考勤日期"+"\t"+"\t"+"考勤结果");
System.out.println(s.getstudentID()+"\t"+s.getname()+"\t"+s.getclassNumber()+"\t"+s.getdate()+"\t"+s.getresult());
System.out.println("查找完成!按回车键返回!");
}
}
}
else if(x==2)
{ flag=-1;
System.out.println("请输入该生姓名:");
name=in.nextLine();
for(i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getname().equals(name))
{
flag=1;
System.out.println("学号"+"\t"+"\t"+"姓名"+"\t"+"班级"+"\t"+"考勤日期"+"\t"+"\t"+"考勤结果");
System.out.println(s.getstudentID()+"\t"+s.getname()+"\t"+s.getclassNumber()+"\t"+s.getdate()+"\t"+s.getresult());
System.out.println("查找完成!按回车键返回!");
}
}
}
if(flag==-1)
{
System.out.println("没有找到此学生!按回车键返回!");
}
in.nextLine();
}
5.3 修改学生记录
修改学生记录,先选择按学号查找或按姓名查找所要修改记录的学生。如果存在此学生,选择修改该生的姓名或学号。如果不存在此学生,显示不存在此信息。具体代码如下所示:
public static void change(String fileName) throws IOException{
Scanner in = new Scanner(System.in);
//创建集合对象
ArrayList<Students> array = new ArrayList<Students>();
//从文件中读取学生信息到集合中
readFile(fileName,array);
int flag,x;
System.out.println("<1>按学号修改");
System.out.println("<2>按姓名修改");
x=in.nextInt();
in.nextLine();
if(x==1)
{
flag=-1;
System.out.println("请输入你要修改的学生学号:");
String studentID=in.nextLine();
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getstudentID().equals(studentID))
{
flag=i;
break;
}
}
if(flag==-1)
{
System.out.println("不存在要找的信息!按回车键返回!");
}
else
{
System.out.println("请输入学生新的学号:");
studentID=in.nextLine();
System.out.println("请输入学生新的姓名:");
String name=in.nextLine();
System.out.println("请输入学生新的班级:");
String classNumber=in.nextLine();
System.out.println("请输入学生新的考勤日期:");
String date=in.nextLine();
System.out.println("请输入学生新的考勤状态:出 勤 √ 旷 课 X 事 假 ▲ 病 假 ● 迟 到 + 早 退 –");
String result=in.nextLine();
//创建一个新的学生对象
Students s=new Students();
s.setstudentID(studentID);
s.setname(name);
s.setclassNumber(classNumber);
s.setdate(date);
s.setresult(result);
array.set(flag, s);
//把集合中的学生信息写到文件中
writeFile(fileName,array);
System.out.println("修改成功!按回车键返回!");
}
}
if(x==2)
{
flag=-1;
System.out.println("请输入你要修改的学生姓名:");
String name=in.nextLine();
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getname().equals(name))
{
flag=i;
break;
}
}
if(flag==-1)
{
System.out.println("不存在要找的信息!按回车键返回!");
}
else
{
System.out.println("请输入学生新的学号:");
String studentID=in.nextLine();
System.out.println("请输入学生新的姓名:");
name=in.nextLine();
System.out.println("请输入学生新的班级:");
String classNumber=in.nextLine();
System.out.println("请输入学生新的考勤日期:");
String date=in.nextLine();
System.out.println("请输入学生新的考勤状态:出 勤 √ 旷 课 X 事 假 ▲ 病 假 ● 迟 到 + 早 退 –");
String result=in.nextLine();
//创建一个新的学生对象
Students s=new Students();
s.setstudentID(studentID);
s.setname(name);
s.setclassNumber(classNumber);
s.setdate(date);
s.setresult(result);
array.set(flag, s);
//把集合中的学生信息写到文件中
writeFile(fileName,array);
System.out.println("修改成功!按回车键返回!");
}
}
in.nextLine();
}
5.4 删除学生记录
删除学生记录功能,先选择按学号删除或按姓名删除。如果存在此学生,删除成功。如果不存在此学生,显示不存在此信息。具体代码如下所示:
public static void Delete(String fileName) throws IOException{
Scanner in = new Scanner(System.in);
//创建集合对象
ArrayList<Students> array = new ArrayList<Students>();
//从文件中读取学生信息到集合中
readFile(fileName,array);
int x,flag=-1;
System.out.println("<1>按学号删除");
System.out.println("<2>按姓名删除");
x=in.nextInt();
in.nextLine();
if(x==1)
{
System.out.println("请输入你要删除学生的学号:");
String studentID=in.nextLine();
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getstudentID().equals(studentID))
{
flag=i;
break;
}
}
if(flag==-1)
{
System.out.println("不存在要找的信息!");
}
else
{
array.remove(flag);
//把集合中的学生信息写到文件中
writeFile(fileName,array);
}
}
if(x==2)
{
System.out.println("请输入你要删除学生的姓名:");
String name=in.nextLine();
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getname().equals(name))
{
flag=i;
break;
}
}
if(flag==-1)
{
System.out.println("不存在要找的信息!");
}
else
{
array.remove(flag);
//把集合中的学生信息写到文件中
writeFile(fileName,array);
}
}
System.out.println("删除成功!按回车键返回!");
in.nextLine();
}
5.5 打印学生考勤数据列表
打印学生考勤数据列表功能,选择部分打印或全部打印,选择部分打印会输出学生姓名和考勤日期和考勤情况。选择全部打印会输出所有学生的所有信息。具体代码如下所示:
public static void Print(String fileName) throws IOException{
Scanner in = new Scanner(System.in);
//创建学生类对象
Students student = new Students();
//创建集合对象
ArrayList<Students> array = new ArrayList<Students>();
//从文件中读取学生信息到集合中
readFile(fileName,array);
if(array.size()==0)
{
System.out.println("无信息,请先添加信息!");
}
else
{
System.out.println("学号"+"\t"+"\t"+"姓名"+"\t"+"班级"+"\t"+"考勤日期"+"\t"+"\t"+"考勤结果");
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
System.out.println(s.getstudentID()+"\t"+s.getname()+"\t"+s.getclassNumber()+"\t"+s.getdate()+"\t"+s.getresult());
}
}
System.out.println("打印完成!按回车键返回!");
in.nextLine();
}
//打印指定考勤日报表
public static void daily(ArrayList<Students>array)
{
Scanner in = new Scanner(System.in);
String date;
int flag=-1;
System.out.println("请输入要查看的日期:");
date=in.nextLine();
System.out.println(date+"的考勤情况:");
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getdate().equals(date))
{ if(flag==-1)
System.out.println("学号"+"\t"+"\t"+"姓名"+"\t"+"班级"+"\t"+"考勤日期"+"\t"+"\t"+"考勤结果");
flag=1;
System.out.println(s.getstudentID()+"\t"+s.getname()+"\t"+s.getclassNumber()+"\t"+s.getdate()+"\t"+s.getresult());
}
}
System.out.println("打印完成!按回车键返回!");
in.nextLine();
}
5.6 对数据进行排序
对数据进行排序功能,自动按学号从小到大进行排序。具体代码如下所示:
public static void paixv(String fileName) throws IOException{
Scanner in = new Scanner(System.in);
//创建集合对象
ArrayList<Students> array = new ArrayList<Students>();
//从文件中读取学生信息到集合中
readFile(fileName,array);
for(int i=0;i<array.size();i++)
{
Students s1=new Students();
s1=array.get(i);
for(int j=i+1;j<array.size();j++)
{
Students s2=new Students();
s2=array.get(j);
String a,b;
a=s1.getstudentID();b=s2.getstudentID();
if(a.compareTo(b)>0)
{
Students temp=new Students();
String studentID=s1.getstudentID();
String name=s1.getname();
String classNumber=s1.getclassNumber();
String date=s1.getdate();
String result=s1.getresult();
temp.setstudentID(studentID);
temp.setname(name);
temp.setclassNumber(classNumber);
temp.setdate(date);
temp.setresult(result);
Students temp2=new Students();
String studentID2=s2.getstudentID();
String name2=s2.getname();
String classNumber2=s2.getclassNumber();
String date2=s2.getdate();
String result2=s2.getresult();
temp2.setstudentID(studentID2);
temp2.setname(name2);
temp2.setclassNumber(classNumber2);
temp2.setdate(date2);
temp2.setresult(result2);
array.set(i, temp2);
array.set(j, temp);
//把集合中学生信息写到文件中
writeFile(fileName,array);
}
}
}
System.out.println("排序成功!按回车建返回!");
in.nextLine();
}
5.7 进行数据统计
进行数据统计功能,选择打印考勤日报表、考勤异常表、请假汇总表。选择打印考勤日报表后输入要打印的考勤日期,完成打印。选择打印考勤异常表会打印除考勤状态为出勤外的所有人。选择打印请假汇总表会打印所有请假的人。具体代码如下所示:
//打印请假汇总表
public static void qingjia(ArrayList<Students>array)
{
Scanner in = new Scanner(System.in);
int sum=0;int flag=-1;
String result="●";
String result1="▲";
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(s.getresult().equals(result)||s.getresult().equals(result1))
{
if(flag==-1)
System.out.println("学号"+"\t"+"\t"+"姓名"+"\t"+"班级"+"\t"+"考勤日期"+"\t"+"\t"+"考勤结果");
flag=1;
System.out.println(s.getstudentID()+"\t"+s.getname()+"\t"+s.getclassNumber()+"\t"+s.getdate()+"\t"+s.getresult());
sum++;
}
}
System.out.println("请假人数:"+sum+"人");
System.out.println("打印完成!按回车键返回!");
in.nextLine();
}
//考勤异常表
public static void kaoqin(ArrayList<Students>array)
{
Scanner in = new Scanner(System.in);
int sum=0;int flag=-1;
String result="√";
for(int i=0;i<array.size();i++)
{
Students s=array.get(i);
if(!s.getresult().equals(result))
{
if(flag==-1)
System.out.println("学号"+"\t"+"\t"+"姓名"+"\t"+"班级"+"\t"+"考勤日期"+"\t"+"\t"+"考勤结果");
flag=1;
System.out.println(s.getstudentID()+"\t"+s.getname()+"\t"+s.getclassNumber()+"\t"+s.getdate()+"\t"+s.getresult());
sum++;
}
}
System.out.println("考勤异常人数:"+sum+"人");
System.out.println("打印完成!按回车键返回!");
in.nextLine();
}
//进行数据统计
public static void Data(String fileName) throws IOException{
//创建集合对象
ArrayList<Students> array = new ArrayList<Students>();
//从文件中读取学生信息到集合中
readFile(fileName,array);
int x;
Scanner in = new Scanner(System.in);
System.out.println("<1>打印考勤日报表");
System.out.println("<2>打印请假汇总表");
System.out.println("<3>打印考勤异常表");
x=in.nextInt();
if(x==1)
{
daily(array);
}
else if(x==2)
{
qingjia(array);
}
else if(x==3)
{
kaoqin(array);
}
}6 调试分析
问题1:如何让用户在输入结束后按回车键返回,更好的实现用户交互?
解决:在函数末尾加入in.nextLine(),达到输入回车后返回主菜单的功能。
问题2:使用集合只能对学生信息和考勤情况进行临时存储,关闭程序时数据就会消失,如何实现对学生信息和考勤情况的永久记录?
解决:在程序中加入文件存储。在代码中加入两个方法,一个是从文件读取信息到集合中的方法,另一个是从集合把信息写到文件中的方法,再将增删查改等方法中的形参换成文件路径名的变量。
心得体会
Java程序设计这门课程对我来说是收获匪浅的一门课程,通过对基础理论知识的学习和实验及作业的训练,逐步对课程有了由浅入深的认识。通过完成这次《Java程序设计》课程设计,让我深刻认识到学习程序设计不能停留在学习它的语法规则,而是要利用学到的知识编写程序,解决实际问题。即把程序设计作为工具,描述解决实际问题的步骤,由计算机帮助我们解决问题。在完成此次课程设计的过程中,我学会了设置变量时命名规范且容易识别。在编写程序时,我做到了每个函数都有注释来说明功能,对参数和返回值也以注释的形式说明用途,关键的语句加入了注释解释,所以我学会了善于利用注释,增强程序的可读性。为了更好的实现用户交互,为了不使输入回车后还未观察数据就返回菜单,我使用了in.nextLine()来吸收回车。在对文件进行读写的操作中,之前也遇到过乱码的问题,不过当时的解决办法都是退而求其次,将汉字信息写成英文字符,一直不知道乱码的症结所在,这次的课设,通过查阅资料找到了问题所在在于文件编码方式与编译器的不符,修改后问题得到解决。但由于时间关系,还有些许想法未能添加在程序中,如:按考勤日期对数据进行排序等。待时间充裕时,定要上手实现此功能,更好的充实程序设计。
参考文献
[1] 张白一等,面向对象程序设计--Java(第三版) 西安:电子科技大学出版社,2018
[2] Y. Daniel Liang Java语言程序设计(基础篇)北京:机械工业出版社,2021.
[3] 郑莉 张宇. Java语言程序设计(第3版). 北京:清华大学出版社, 2021.