前言
相对于其他主流的编程语言,Java显得十分年轻,实际上,按Java的正式推出时间来算,她只比我大两岁(暴露年龄),但是这样一位年轻的小姐姐,在短短的二十几年时间里,已经成为了编程语言的中流砥柱,在注重用户终端的今天,Java甚至比其前辈发挥着更大的作用。
这是我开始学习Java后的第一个小项目,入门级别的难度,但却能启蒙,或许多年后我回头看这个项目会觉得当时很幼稚,但正是有了这个第一步,我才能回头。
正文
项目要求:完成一个图书管理系统,要求能存储图书的书号、作者姓名、标题(书名)、出版社、定价五个信息,并且能通过文件存储和读取书籍信息,能在管理系统中进行增删查改等操作。
一、构建类
1.书类(Book)
用于存储书的信息,基本的如上所述,其他的仍能扩展。
属性: 书号(BkNum);作者姓名(Writer);书名(BkName);出版社(PubHouse);定价(Price);
方法: 传参构造方法(Book(×××));手动构造方法(Book);读取方法(get×××);设置方法(set×××);打印方法(toString);
2.管理类(Manage)
用于执行相应的管理操作,基本的如上所述,其他的仍能扩展。
属性: 与Book类相同,用于对接数据,同时扩展了关键词(key),菜单选项(a);信息暂存向量容器 ;
方法: 自定构造方法(Manage);菜单(Menu);搜索(Search);删除(Delete);修改(Modify);
3.主类(Manage)
类似于C语言的main函数,程序从这里开始执行,调用各种子函数,但在Java中,main是一个类。
二、代码实现
1.书类(Book)
属性:
private static final long serialVersionUID = 1L;//序列化接口
private String BkNum;//书号
private String Writer;//作者姓名
private String BkName;//标题(书名)
private String PubHouse;//出版社
private String Price;//定价
方法:
(1)传参构造
将学生的各项参数直接传入,一步成形,可用于要录入大量学生信息时。
public Book(String BkNum, String Writer, String Bkname, String PubHouse, String Price)//直接传参构造函数
{
this.BkNum = BkNum;
this.Writer = Writer;
this.BkName = Bkname;
this.PubHouse = PubHouse;
this.Price = Price;
}
(2)手动构造
当需要输入的学生信息较为少量时,可直接通过此方法输入学生信息。
public Book()//手动构造函数
{
Scanner sca = new Scanner(System.in);
System.out.print("请输入书号:");
BkNum = sca.next();
System.out.print("请输入作者姓名:");
Writer = sca.next();
System.out.print("请输入标题(书名):");
BkName = sca.next();
System.out.print("请输入出版社:");
PubHouse = sca.next();
System.out.print("请输入定价:");
Price = sca.next();
}
(3)获取信息
用于特殊情况下要获取私有成员信息。
public String getBkNum()//一系列读取私有成员的方法
{
return BkNum;
}
public String getWriter()
{
return Writer;
}
public String getBkName()
{
return BkName;
}
public String getPubHouse()
{
return PubHouse;
}
public String getPrice()
{
return Price;
}
(4)修改信息
用于特殊情况下修改私有成员信息。
public void setBkNum(String BkNum)//一系列单独设置私有成员的方法
{
this.BkNum = BkNum;
}
public void setWriter(String Writer)
{
this.Writer = Writer;
}
public void setBkName(String BkName)
{
this.BkName = BkName;
}
public void setPubHouse(String PubHouse)
{
this.PubHouse = PubHouse;
}
public void setPrice(String Price)
{
this.Price = Price;
}
2.管理类(Manage)
属性:
int key,a;
String Writer,BkName,PubHouse,BkNum,Price;
Vector<Book> vector = new Vector<Book>();
Scanner sc = new Scanner(System.in);//类中全局定义一个输入流,便于需要输入时调用
方法:
(1)自定构造
将文件中的数据读取到程序的向量容器中。
public Manage() throws Exception//偷个懒,自己不写异常了,直接将之抛给外围处理
{
File f = new File("C:/Books.dat");
if (f.exists() == true)
{
FileInputStream in = new FileInputStream(f);
ObjectInputStream oin = new ObjectInputStream(in);
Book[] aa=(Book[])oin.readObject();
vector.clear();
for(Book x:aa)
vector.add(x);
oin.close();
}
}
(2)菜单
将增删查改等操作以菜单形式显示出来,便于用户调用。
public void menu()
{
System.out.println("/***************************************/");
System.out.println("/***************************************/");
System.out.println("请输入你选择的功能:");
System.out.println("1.打印系统列表");
System.out.println("2.增加");
System.out.println("3.查找");
System.out.println("4.删除");
System.out.println("5.修改");
System.out.println("6.读取");
System.out.println("7.保存");
System.out.println("8.退出");
System.out.print("请输入你的选择(必须为数字序号):");
a = sc.nextInt();
System.out.println("/***************************************/");
System.out.println("/***************************************/");
if(a==1||a==2||a==3||a==4||a==5||a==6||a==7||a==8)//判断输入是否符合要求
switch(a)
{
case 1:
System.out.println("系统列表为:");
for(int i=0;i<vector.size();i++)
System.out.println(vector.get(i).toString());
menu();//通过调用自身的方式返回根目录,下同
break;
case 2 :
vector.add(new Book());
menu();
break;
case 3:
System.out.println("查询关键词:1、书号,2、作者姓名,3、标题,4、出版社,5、定价。");
System.out.print("请选择关键词:");
key=sc.nextInt();
Search(key);//调用搜索函数
break;
case 4:
System.out.println("要删除的书的关键词:1、书号,2、作者姓名,3、标题,4、出版社,5、定价。");
System.out.print("请选择关键词:");
key=sc.nextInt();
Delete(key);//调用删除函数
break;
case 5:
System.out.println("请输入要修改的书号:");
BkNum = sc.next();//为避免造成代码冗余以及用户误操作,此处只允许输入书号,如果用户不知道书号可结合查找功能使用
Modify(BkNum);//调用修改函数
case 6:
try
{
File f = new File("C:/Books.dat");
if (f.exists() == true)
{
FileInputStream in = new FileInputStream(f);
ObjectInputStream oin = new ObjectInputStream(in);
Book[] aa=(Book[])oin.readObject();
vector.clear();
for(Book x:aa)
vector.add(x);
oin.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}//抛出异常,下同
System.out.println("已完成。");
menu();
break;
case 7:
try
{
File f = new File("C:/Books.dat");
FileOutputStream out = new FileOutputStream(f);
ObjectOutputStream oout = new ObjectOutputStream(out);
Book[] ob=vector.toArray(new Book[vector.size()]);
oout.writeObject(ob);
oout.close();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("已完成。");
menu();
break;
case 8:
sc.close();//关闭输入流
System.out.println("再 见");
System.exit(0);
}
else
{
System.out.println("输入错误!");
menu();
}
}
(3)搜索
用于在已存信息中搜索需要的信息。
public void Search(int key)
{
String keyword = null;//用于存储用户所选择的关键词,以便在提示语中显示出来
String key1 = null;//用户输入的检索词
int check = 0;//哨兵变量,用于监测是否产生查询结果
if(key==1||key==2||key==3||key==4||key==5)
switch(key)
{
case 1:
keyword = "书号";
break;
case 2:
keyword = "作者姓名";
break;
case 3:
keyword = "标题";
break;
case 4:
keyword = "出版社";
break;
case 5:
keyword = "定价";
break;
}
else
{
System.out.println("输入错误!");
menu();
}
System.out.print("请输入" + keyword + ":");
key1 = sc.next();
switch(key)
{
case 1:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getBkNum().equals(key1))
{
System.out.println(vector.get(i).toString());
check = 1;//如果产生搜索结果,则修改哨兵变量,下同
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 2:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getWriter().equals(key1))
{
System.out.println(vector.get(i).toString());
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 3:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getBkName().equals(key1))
{
System.out.println(vector.get(i).toString());
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 4:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getPubHouse().equals(key1))
{
System.out.println(vector.get(i).toString());
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 5:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getPrice().equals(key1))
{
System.out.println(vector.get(i).toString());
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
}
menu();
}
(4)删除
用于在已存信息中删除信息。
public void Delete(int key)
{
String keyword = null;
String key1 = null;
int check = 0;
if(key==1||key==2||key==3||key==4||key==5)
switch(key)
{
case 1:
keyword = "书号";
break;
case 2:
keyword = "作者姓名";
break;
case 3:
keyword = "标题";
break;
case 4:
keyword = "出版社";
break;
case 5:
keyword = "定价";
break;
}
else
{
System.out.println("输入错误!");
menu();
}
System.out.print("请输入" + keyword + ":");
key1 = sc.next();
switch(key)
{
case 1:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getBkNum().equals(key1))
{
vector.remove(i);
i--;//将扫描点回溯,避免遗漏,下同
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 2:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getWriter().equals(key1))
{
vector.remove(i);
i--;
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 3:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getBkName().equals(key1))
{
vector.remove(i);
i--;
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 4:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getPubHouse().equals(key1))
{
vector.remove(i);
i--;
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
case 5:
for(int i=0; i<vector.size(); i++)
{
if(vector.get(i).getPrice().equals(key1))
{
vector.remove(i);
i--;
check = 1;
}
}
if(check != 1)
System.out.println("无查询结果!");
break;
}
System.out.println("已完成。");
menu();
}
(5)修改
用于在已存信息中修改信息。
public void Modify(String BkNum)
{
int loca = 0;
System.out.println("您要修改的书为:");
for(int i=0;i<vector.size();i++)
if(vector.get(i).getBkNum().equals(BkNum))
{
System.out.println(vector.get(i).toString());
loca = i;
}//检索书号,输出要修改的书的详细信息,同时用loca变量确定要修改的书的位置,便于修改属性
System.out.println("要修改的关键词:1、书号,2、作者姓名,3、标题,4、出版社,5、定价。");
System.out.print("请选择关键词:");
key=sc.nextInt();
if(key==1||key==2||key==3||key==4||key==5)
{
String elm=null;
System.out.print("改为:");
elm=sc.next();
switch(key)
{
case 1:
vector.get(loca).setBkNum(elm);
break;
case 2:
vector.get(loca).setWriter(elm);
break;
case 3:
vector.get(loca).setBkName(elm);
break;
case 4:
vector.get(loca).setPubHouse(elm);
break;
case 5:
vector.get(loca).setPrice(elm);
break;
}
System.out.println("已完成。");
menu();
}
else
{
System.out.println("无此关键词!");
menu();
}
}
3.主类(Main)
属性:无
方法:
仅包含对菜单的调用和异常处理。
public static void main(String args[])
{
Manage mag;
try {
mag = new Manage();
mag.menu();
} catch (Exception e) {
e.printStackTrace();
}
}
后记
完成这个图书管理系统实际上并不难,对于基础部分,只需要这三个类往上一套就能完成,而要完成扩展,也只需要在这个基础上添砖加瓦,实际上,对于任何一类“××管理系统”,其主要部分也只包括了要管理的类、产生管理操作的类、主类,后面两者可以整合在一起。如果需要将其形成人机交互界面,也只需要将之整体搬移即可,其逻辑关系并没有太大的变化。
换句话说,这个图书管理系统不单单是一个项目,而是一个例子,一个模板,在这之上可以千变万化。