Java阶段三:基础项目—家庭记录收支程序

目录

需求说明

软件设计

界面展示

设计判断输入的各个方法

1. 判断主界面功能选择输入的方法

2. 判断输入是否全为数字

3. 判断输入是否全为汉字

添加收入记录的方法

添加支出记录的方法

查看信息记录的方法

确认退出的方法

二维数组扩容的方法

总结

需求说明


该软件能够记录家庭的收入、支出,并能够打印收支明细表

项目采用分级菜单方式。主菜单如下:

-----------------家庭收支记账软件-----------------

                        1 收支明细

                        2 登记收入

                        3 登记支出

                        4 退       出 请选择(1-4):_

1. 假设家庭起始的生活基本金为10000元。

2. 查询收支明细(菜单1)时,将显示所有的收入、支出名细列表。

3. 每次登记收入(菜单2)后,收入的金额应累加到基本金上,并记录本次收入明细,以便后续的查询。

4. 每次登记支出(菜单3)后,支出的金额应从基本金中扣除,并记录本次支出明细,以便后续的查询。

5. 点击退出(菜单4)后,确认该操作后即可退出程序。

软件设计


界面展示

设计思路:

(怎样来保存数据?) 我们要保存一组多维度的数据使用一维数组难以做到,此时应该使用二维数组进行数据存取。

(界面效果要怎样设计?) 经过观察发现当我们选择退出后程序才会结束运行,所以界面的展示应该写在一个死循环里面。

(怎样选择要执行的操作?) 根据我们所学的基础知识,不难发现使用switch语句就可以做到。

为了简化主界面代码,我把对应实现的功能设计成各个方法,使用时直接调用即可。(设计的各个方法写在本类中,主方法main之外)

界面效果的代码:

//导包
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Demo {

    //定义私有静态对象,创建后每个方法都可使用
    private static Scanner sc = new Scanner(System.in);
    //定义账户余额,并设置初始值
    private static int sumMoney = 10000;
    //定义数组中记录的条数
    private static int count = 0;

    public static void main(String[] args) {
        //定义二维数组并设置容量
        String[][] arr = new String[10][4];
        //定义一个boolean值,用于判断主界面的循环
        boolean flag=true;

        while(flag){
            //调用数组扩容的方法
            arr = expandArray(arr);
            System.out.println("\n----------------家庭收支记账软件----------------\n");
            System.out.println("                    1.收支明细");
            System.out.println("                    2.登记收入");
            System.out.println("                    3.登记支出");
            System.out.println("                    4.退   出\n");
            System.out.print("请选择(1-4): ");
            //输入你想要进行的操作数
            String num = sc.next();
            //调用判断输入的方法
            char b1 = readMenuSelection(num);

            switch(b1){
                case '1':
                    //调用查看信息的方法
                    readInfo(arr);
                    break;
                case '2':
                    //调用添加收入记录的方法
                    addRecord(arr);
                    break;
                case '3':
                    //调用添加支出记录的方法
                    reduceRecord(arr);
                    break;
                case '4':
                    //调用选择退出的方法
                    boolean b = quitSystem();
                    if(b==true)
                        flag=false;
                    else break;
            }
        }
    }
}

界面效果图: 

设计判断输入的各个方法

1. 判断主界面功能选择输入的方法

目的:用户输入错误时给出提示,直到输入正确的操作数字符后再进行操作,而不是输入错误,程序就直接停止运行。

    //创建判断输入的方法
    //返回值类型char(需要返回一个字符和操作数字符匹配)
    //参数为String(用户输入的类型是String)
    public static char readMenuSelection(String n) {
        char c;
        //设置死循环,满足条件后退出,直到获取到正确操作数字符
        while(true){
            //获取参数字符串的第一个字符
            c = n.charAt(0);
            //判断是否对应给定的操作数字符
            if (c != '1' && c != '2' && c != '3' && c != '4') {
                System.out.print("输入数字错误,请按提示正确输入:");
                String n1 = sc.next();
                n = n1;
            } else break;
        }
        //返回给定的正确操作数字符
        return c;
    }

2. 判断输入是否全为数字

目的: 在用户输入收入金额和支出金额时进行判断,为了使输入的内容规范,要求输入的字符串只能是数字,然后再转换成 int 类型的数字进行操作。

    //把全为数字的字符串转换为int类型,并返回其数值
    public static int printInt(String x){
        //调用判断字符串是否全为数字的方法的返回值进行判断
        if(isNumberic(x)){
            //将获取到的数字字符串转为int类型的数字
            int y = Integer.parseInt(x);
            return y;
        }else{
            //写一个死循环,直到用户输入全为数字字符串时才停止
            while(true){
                System.out.print("你输入的值无意义! 请你重新输入: ");
                String num = sc.next();
                if(isNumberic(num)){
                    int y1 = Integer.parseInt(num);
                    return y1;
                }

            }
        }
    }

    //判断字符串是否全是数字,是返回true,否则返回false
    //设置参数为String类型的字符串
    public static boolean isNumberic(String str) {
        //使用正则表达式进行判断是否全为数字
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

3. 判断输入是否全为汉字

目的:在用户输入收入说明和支出说明时进行判断,为了使输入的内容规范,要求输入的字符串只能是汉字。

    //判断字符串是否全为汉字,是则返回,否则从新输入字符串
    public static String printString(String x){
        if(isChinese(x)){
            return x;
        }else{
            while(true){
                System.out.print("输入错误! 请你重新输入: ");
                String t = sc.next();
                if(isChinese(t)){
                    return t;
                }
            }
        }
    }

    //判断字符串是否全是汉字,是返回true,否则返回false
    public static boolean isChinese(String str) {
        //使用正则表达式进行判断是否全为汉字
        Pattern p_str = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher m = p_str.matcher(str);
        if(m.find()&&m.group(0).equals(str)){
            return true;
        }
        return false;
    }

添加收入记录的方法

设计思路:根据需求可知用户首先应该输入收入的金额及说明,并且判断输入的规范性;然后再算出增加收入后的总金额;最后将各个记录保存到二维数组中。(将数组中的记录条数加1)

代码实现:

    //创建添加收入记录的方法
    //该方法直接使用无需返回值,设置参数为String类型的二维数组
    public static void addRecord(String[][] arr){
        System.out.println("收入的金额:");
        String num1 = sc.next();
        //调用判断输入是否全为数字的方法
        int money = printInt(num1);
        System.out.println("收入的原因:");
        String b1 = sc.next();
        //调用判断输入是否全为汉字的方法
        String because = printString(b1);
        arr[count][0]="收入";
        //计算收入的总金额值
        sumMoney += money;
        //将int类型的总金额和收入金额转为String类型
        String t1=String.valueOf(sumMoney);
        String t2=String.valueOf(money);
        arr[count][1]=t1;
        arr[count][2]=t2;
        arr[count][3]=because;
        //数组中的记录条数加1
        count++;
        System.out.println("添加成功!");
    }

效果展示:

添加支出记录的方法

设计思路:跟添加收入记录的方法大同小异,可对比起来设计。(将数组中的记录条数加1)

代码实现:

    //创建添加支出记录的方法
    public static void reduceRecord(String[][] arr){
        System.out.println("支出的金额:");
        String num2 = sc.next();
        int money1 = printInt(num2);
        System.out.println("支出的原因:");
        String b2 = sc.next();
        String because1 = printString(b2);
        arr[count][0]="支出";
        sumMoney -= money1;
        String t3=sumMoney+"";
        String t4=money1+"";
        arr[count][1]=t3;
        arr[count][2]=t4;
        arr[count][3]=because1;
        count++;
        System.out.println("添加成功!");
    }

效果展示:

查看信息记录的方法

设计思路:用户在还没有录入信息的时候也有可能会进行查询操作,此时我们首先就应该进行判断并给出提示信息;然后再进行二维数组的遍历;最后进行判断查询的类别,格式化输出记录。

代码实现:

    //创建查看信息的方法
    public static void readInfo(String[][] arr){
        //判断二维数组是否为空,如果为空给出提示信息,如不为空进行查询操作
        if(arr[0][0]==null){
            System.out.println("暂无收支记录,账户余额为:10000元");
        }else{
            System.out.println("收支\t\t账户总金额\t\t收支金额\t\t说   明");
            //循环二维数组
            for(int i=0; i<arr.length; i++){
                //循环二维数组中的一维数组
                for(int j=0; j<arr[i].length; j++){
                    if(arr[i][j]!=null){
                        //判断查询的记录是收入还是支出,以便给出不同的展示效果
                        if(arr[i][0]=="收入"){
                            //格式化输出,为了美观
                            System.out.println(String.format("%-6s %-15s +%-11s %-8s",arr[i][j],arr[i][1],arr[i][2],arr[i][3]));
                            break;
                        }else{
                            System.out.println(String.format("%-6s %-15s -%-11s %-8s",arr[i][j],arr[i][1],arr[i][2],arr[i][3]));
                            break;
                        }
                    }
                }
            }
        }
    }

效果展示:

确认退出的方法

设计思路:给出提示语句让用户输入,再对用户的输入进行判断,如果输入的是y或者Y表示用户确认退出返回 true,输入其他则认为用户选择取消退出返回 false。

代码实现:

    //创建选择退出的方法
    //返回值设置为boolean类型,无参数传递
    public static boolean quitSystem(){
        System.out.print("确定退出?(输入y确认操作): ");
        //单个字符不能直接输入,此时我们输入一个字符串
        String t = sc.next();
        //获取字符串的第一个字符
        char tc = t.charAt(0);
        //获取该字符的ASCII码
        int tc1 = (int)tc;
        //y的ASCII码121,Y的ASCII码89
        //判断用户输入的字符串是否是一个字符并且为y或则Y,满足条件则返回true,否则返回false
        if((tc1==121 && t.length()==1) || (tc1==89 && t.length()==1)){
            System.out.println("\n退出成功!");
            return true;
        }else{
            System.out.println("\n已取消退出");
            return false;
        }
    }

效果展示:

二维数组扩容的方法

设计目的:二维数组的容量是固定的,可以看出本次二维数组的最大存储数据条数为10,当我们录入的记录条数超过这个限制时,程序就会报错并且结束运行,给用户不好的体验,因此,对于给二维数组的扩容就很有必要。

设计思路:定义一个扩容后的新二维数组,再判断原二维数组中的数据条数达到最大值时,如果达到了最大值,就把原二维数组中的数据传入到新二维数组,最后返回新二维数组;如果没有达到最大值时,最后返回原二维数组。

代码实现:

    //二维数组扩容
    //设置返回值为二维数组,参数也为二维数组
    public static String[][] expandArray(String[][] arr){
        //定义一个在原二维数组基础上扩容的二维数组
        String[][] arr1 = new String[arr.length+10][4];
        //判断传入的二维数组的数据条数是否已经达到最大容量
        if(arr[arr.length-1][0] != null){
            //使用循环把传入的二维数组中的数据赋值给扩容后的新二维数组
            for(int i=0; i<arr.length; i++){
                for(int j=0; j<4; j++){
                    arr1[i][j] = arr[i][j];
                }
            }
            //返回扩容后的新二维数组
            return arr1;
        }else {
            //返回原二维数组
            return arr;
        }
    }

总结


        该程序总的来说还是比较简单,非常适合作为 Java 初学者的练习小项目,这也是小编初学 Java 以来做的第一个小项目;在编写代码的时候还是需要注意部分的细节 (比如:添加记录后的二维数组记录条数要增加 1、int 类型数据转为 String 类型、单个字符不能直接输入,应该输入字符串后获取单个字符...);以上代码完全可以正常运行,希望对正在学习 Java 的你有许些帮助,如有任何问题,请联系小编~

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

South.return

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值