之前说的加强版项目来了!!!
这次是用Java基础中的流程控制、面向对象、集合、IO流、日志、异常处理的简单技术实现的小项目
思想(四个类):
①注册登录类
②记账信息类
③异常处理类
④记账本操作类
一、注册登录类
此类中实现用户登录和注册的简单操作,只有正常登录成功才能进行下一步的操作
package tallyBook;
import java.util.Scanner;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
//登录注册类:只有登录成功才能进入记账本
public class Registe implements Serializable{
private static final long serialVersionUID = 1L;
String admin;//用户名
String password;//密码
//设置构造器
public Registe() {
super();
}
public Registe(String admin,String password) {
super();
this.admin=admin;
this.password=password;
}
//登录注册视图类
public void registeView() throws TallyBookException{
Registe re1=new Registe("曹汉三","123456");
write(re1);
Registe re2=new Registe("","");
Scanner in=new Scanner(System.in);
boolean flag=true;
System.out.println("-----------------欢迎使用汉三的记账本----------------------------------\n\n");
System.out.println("---------------------登录界面------------------\n");
while(flag) {
System.out.print("请选择你需要进行的操作(1.登录(已有账号) 2.注册(没有账号)):");
int num=in.nextInt();
if(num==1||num==2) {
switch(num) {
case 1:
System.out.print("请输入用户名:");
String name=in.next();
System.out.print("请输入密码:");
String ps=in.next();
if(name.equals(re1.admin)&&ps.equals(re1.password)) {
System.out.println("登录成功!!!");
flag=false;
}else if(name.equals(re2.admin)&&ps.equals(re2.password)) {
System.out.println("登录成功!!!");
flag=false;
}else {
System.out.println("账号或密码输入错误,请重新输入!!!");
}
break;
case 2:
System.out.print("请输入用户名:");
String name2=in.next();
System.out.println("请输入密码:");
String ps2=in.next();
re2.admin=name2;
re2.password=ps2;
write(re2);
System.out.println("注册成功,请重新登录!!!");
break;
}
}else {
throw new TallyBookException("输入失败,原因是没有按照要求输入!!!");
}
}
read();
}
public void write(Registe re) {
Registe re3=re;
FileOutputStream fos=null;
ObjectOutputStream oos=null;
//写入流
try {
fos=new FileOutputStream("D:/re3.txt");
oos=new ObjectOutputStream(fos);//对象流
oos.writeObject(re3);//对象写入
oos.flush();//刷新
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(oos!=null)
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//文件读取
public Registe read() {
Registe re3=null;
FileInputStream fis=null;
ObjectInputStream ois=null;
try {
File file=new File("D:/re3.txt");
fis=new FileInputStream(file);
ois=new ObjectInputStream(fis);
//读取
re3=(Registe)ois.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}finally {//关闭流资源
try {
if(ois!=null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fis!=null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return re3;
}
}
里面有文件读入和写出方法,用到了对象流目前我也不是很了解,这两个方法就是为了老师需要才写的,没有什么用处目前哈哈。
二、记账信息类
此类定义了每天消费的基本属性类别,还有星期几,逻辑十分清晰,对我们这样的初学者很友好
package tallyBook;
//⑤支出的分类 :餐饮,交通,购物,其它。收入无分类
public class Expenditure {
private String day;//星期几
private int id;//记录星期几
private double food;//餐饮支出
private double traffic;//交通出行
private double shop;//购物消费
private double other;//其它支出
private double income;//收入
private double sum;
public Expenditure() {
}
public Expenditure(String day,int id,double food,double traffic,double shop,double other,double income,double sum) {
super();
this.day=day;
this.id=id;
this.food=food;
this.traffic=traffic;
this.shop=shop;
this.other=other;
this.income=income;
this.sum=sum;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id=id;
}
public double getFood() {
return food;
}
public void setFood(double food) {
this.food = food;
}
public double getTraffic() {
return traffic;
}
public void setTraffic(double traffic) {
this.traffic = traffic;
}
public double getShop() {
return shop;
}
public void setShop(double shop) {
this.shop = shop;
}
public double getOther() {
return other;
}
public void setOther(double other) {
this.other = other;
}
public double getIncome() {
return income;
}
public void setIncome(double income) {
this.income = income;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day=day;
}
public double getSum() {
return sum;
}
public void setSum(double sum) {
this.sum=sum;
}
@Override
public String toString() {
String str=day+"\t"+food+"\t"+traffic+"\t"+shop+"\t"+other+"\t"+income;
return str;
}
}
基本没有需要讲解的地方,都是很基础的操作
三、异常处理类
本来这个类是我用来处理各种异常的,当哪里输出不正确的时候就会提示相应的错误信息,并重新输入,我想的很好,实现有点麻烦,然后就只有登录注册哪里用到了这个异常类,我把错误抛给了main方法然后在main方法中进行了try-catch解决,报错后就会直接不用登录就进入到下面的代码里面去了,这是一个bug,等后面学好了再来解决
package tallyBook;
//异常处理类 :用来处理各个功能遇到的异常
public class TallyBookException extends Exception{
private static final long serialVersionUID = -3387514889948L;
public TallyBookException() {
}
public TallyBookException(String msg) {
super(msg);
}
}
定义异常类,可以去看看尚硅谷的课程,有详细的介绍
四、记账操作类
这个类我觉得是写的最好的,他结合了我们的生活实际,实现了我们想要记账的一些功能,比如输出这周的消费占比或者是输出这周的消费类别占比,有些小细节的东西可以自行领悟,比如用数组来存放一周七天的消费或者格式化输出百分比等等。这里面还涉及到了日志的使用,想要工具的可以评论区留言我发你。
package tallyBook;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import org.apache.log4j.Logger;
public class TallyBookOper {
double hope=0;//期望消费金额
double sum1=0;//当消费金额大于期望消费金额时,做出提示
List<Expenditure> list=new LinkedList<Expenditure>();
Scanner in=new Scanner(System.in);
DecimalFormat df = new DecimalFormat("0.0");//将输出的百分比格式化
private static Logger logger=Logger.getLogger(TallyBookOper.class.getName());
{
//初始化七天的消费
Expenditure one=new Expenditure("星期一",1,0,0,0,0,0,0);
Expenditure two=new Expenditure("星期二",2,0,0,0,0,0,0);
Expenditure three=new Expenditure("星期三",3,0,0,0,0,0,0);
Expenditure four=new Expenditure("星期四",4,0,0,0,0,0,0);
Expenditure five=new Expenditure("星期五",5,0,0,0,0,0,0);
Expenditure six=new Expenditure("星期六",6,0,0,0,0,0,0);
Expenditure seven=new Expenditure("星期天",7,0,0,0,0,0,0);
//将数据添加到集合中
list.add(one);
list.add(two);
list.add(three);
list.add(four);
list.add(five);
list.add(six);
list.add(seven);
}
//菜单类
public void menu() {
System.out.println("\n-------------欢迎使用汉三的周记本(仅能记录一周的消费记录)-----------\n");
System.out.print("请输入你想要进行的操作(0.查看这周每天的消费占比 1.记录一周某天的消费 2.设置本周的期望消费金额 3.查看本周的消费情况 4.查看类别消费情况 5.修改某天的收入情况 6.退出):");
int num=in.nextInt();
switch(num) {
case 0:
Proportion_Of_Daily_Consumption();
break;
case 1:
recordthisday();
break;
case 2:
setExpend();
break;
case 3:
seeAll();
break;
case 4:
consumption_Categories();
break;
case 5:
updateIncome();
break;
case 6:
System.out.print("是否确认退出(Y/N):");
String flag=in.next();
if("Y".equalsIgnoreCase(flag)) {
System.out.println("退出成功!!!");
System.exit(0);
}
break;
}
}
//记录当日消费
public void recordthisday() {
System.out.println("\n---------------记录当日消费----------------------\n");
System.out.print("请输入今天所对应的星期编号(1-7):");
int num=in.nextInt();
for(int i=0;i<list.size();i++) {
if(num==((Expenditure) list.get(i)).getId()) {
double sum=0;
System.out.print("请输入"+list.get(i).getDay()+"的餐饮支出:");
double food=in.nextDouble();
System.out.print("请输入"+list.get(i).getDay()+"的交通支出:");
double traffic=in.nextDouble();
System.out.print("请输入"+list.get(i).getDay()+"的购物支出:");
double shop=in.nextDouble();
System.out.print("请输入"+list.get(i).getDay()+"的其它支出:");
double other=in.nextDouble();
System.out.print("请输入"+list.get(i).getDay()+"的总收入:");
double income=in.nextDouble();
sum=food+traffic+shop+other;
sum1+=sum;
Expenditure et=new Expenditure(list.get(i).getDay(),i+1,food,traffic,shop,other,income,sum);
list.set(i, et);
}
}
if(hope>0) {
if((hope-sum1)<0) {
System.out.println("\n这周的期望消费金额已花光,请理性消费");
}else if(sum1>hope*0.5) {
System.out.println("\n请注意这周的消费已超过期望消费金额的百分之五十,剩余金额:"+(hope-sum1)+"元");
}else if(sum1>hope*0.8) {
System.out.println("\n请注意这周的消费已超过期望消费金额的百分之八十,剩余金额:"+(hope-sum1)+"元");
}
}
System.out.println("\n------------------------------------------------------------------------");
}
//设置这周的消费金额,作出提示
public void setExpend() {
System.out.println("\n-------------设置本周的期望消费金额,对本周的消费情况进行一定的提示-----------");
System.out.print("请输入这周的期望消费金额:");
hope=in.nextDouble();
System.out.println("设置成功!!!");
System.out.println("\n------------------------------------------------------------------------");
}
//查看各个类别的消费占比:总支出sum1,一周的消费占比,每天的消费占比
public void consumption_Categories() {
System.out.println("\n---------------------------查看本周各个类别的消费占比------------------------");
double sumFood=0;
double sumTraffic=0;
double sumShop=0;
double sumOther=0;
for(int i=0;i<list.size();i++) {
sumFood+=list.get(i).getFood();
sumTraffic+=list.get(i).getTraffic();
sumShop+=list.get(i).getShop();
sumOther+=list.get(i).getOther();
}
System.out.println("消费类别\t\t消费占比");
System.out.println("餐饮支出:\t"+df.format((sumFood/sum1)*100)+"%");
System.out.println("交通出行:\t"+df.format((sumTraffic/sum1)*100)+"%");
System.out.println("购物支出:\t"+df.format((sumShop/sum1)*100)+"%");
System.out.println("其它支出:\t"+df.format((sumOther/sum1)*100)+"%");
System.out.println("\n------------------------------------------------------------------------");
}
//查看这周每天的消费占比
public void Proportion_Of_Daily_Consumption() {
System.out.println("\n--------------每天的消费占比--------------\n");
System.out.println("时间\t\t百分比");
double sum2=0;//记录这周的总消费
double sum[]=new double[7];
for(int i=0;i<list.size();i++) {
sum[i]=list.get(i).getFood()+list.get(i).getTraffic()+list.get(i).getShop()+list.get(i).getOther();
sum2+=sum[i];
}
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i).getDay()+"\t\t"+df.format((sum[i]/sum2)*100)+"%");
}
}
//查看这周的消费情况
public void seeAll() {
System.out.println("时间\t餐饮\t交通\t购物\t其它\t收入\n");
for(Object obj:list) {
System.out.println(obj);
}
}
//更新某天的收入情况
public void updateIncome() {
System.out.println("\n------------------更新某天的收入情况---------------------");
System.out.print("请输入今天所对应的星期编号(1-7):");
int num=in.nextInt();
for(int i=0;i<list.size();i++) {
if(num==((Expenditure) list.get(i)).getId()) {
System.out.println("原记录金额为:"+list.get(i).getIncome());
System.out.println("请输入你要修改的金额:");
list.get(i).setIncome(in.nextDouble());
System.out.println("修改成功!!!");
break;
}
}
}
public static void main(String[] args) {
Registe re=new Registe();
TallyBookOper tbo=new TallyBookOper();
try {
re.registeView();
} catch (TallyBookException e) {
logger.info("输入失败,原因是:"+e.getMessage());
}
while(true) {
tbo.menu();
}
}
}