MENU

Java-12 项目一:家庭记账软件

August 17, 2023 • Read: 86 • Java阅读设置

Java基本语法

项目一:家庭记账软件

1 Utility工具类

1) API

  • Scanner.next() & Scanner.nextLine()

    • Scanner.next():读取当前Scanner缓冲区中有效字符。当第一次调用该Scanner时,会给用户提供缓冲区(即初始没有缓冲区时)。
      无效字符包括空格tab回车
      空格tab可以作为分隔符,每碰到一个分隔符,相当于开始下一次读数据。
      回车可以作为结束符,没碰到一个结束符,结束用户的输入。
      用户输入的有效字符之前的无效字符全部忽略,而用户输入的有效字符之后跟着的空格tab作为分隔符,回车作为结束符,而最后一个有效字符之后的所有无效字符,包括结束符,虽然不会被作为数据读入,但会保留在当前缓冲区中,即当前的Scanner对象中。
      2023-08-17T13:31:39.png
      每次输入都是ok 即后跟两个空格,可以看到,最后一个next()最后的两个空格及最后的结束符回车保留在了Scanner s1缓冲区中,使得str3读取到的字符为 \enter,由于回车也是nextLine()的结束符,因此str3的数据就是两个空格。
      2023-08-17T13:48:49.png
    • Scanner.nextLine():读取当前Scanner缓冲区中的所有字符。当第一次调用该Scanner时,会给用户提供缓冲区(即初始没有缓冲区时)。
      不存在无效字符,会读取所有字符。其中空格tab都会作为数据,而回车会作为结束符,不会作为数据。
      2023-08-17T13:53:10.png
  • Scanner.hasNext():给用户提供当前Scanner的输入缓冲区,如果用户进行输入,则返回true,并将用户输入的内容(缓冲区的数据)读入到Scanner缓冲区中。如果用户不进行输入,则将一直等待用户输入。该方法不会返回false

    • hasNext()将用户输入的内容读入到缓冲区的方式与next()一致,会将第一个有效字符之前的所有无效字符忽略,将有效字符之后的空格tab作为分隔符,将回车作为结束符,并且会将最后一个有效字符之后的所有无效字符读入到缓冲区。
    • hasNext()next()不同点在于,hasNext()要么等待用户输入,要么返回true并且是将用户输入的内容读入到当前Scanner的缓冲区中。而next()是返回缓冲区中的数据。
      2023-08-17T12:40:00.png
      2023-08-17T12:42:53.png
      2023-08-17T14:12:18.png
  • Scanner.hasNextLine():与hasNext()类似。不同之处在于将用户输入的内容读到缓冲区的方式与nextLine()一致,即不会忽略任何字符,不存在无效字符,所有字符都会读入到缓冲区。
    2023-08-17T14:18:00.png
  • Integer.parseInt(String s):返回字符串参数s的十进制整数。要求字符串参数s是十进制数字符构成的,第一位可以是符号+-,最终返回的是带符号的十进制整数。

    • 若无法转换,则会抛出异常NumberFormatException
      2023-08-18T13:40:17.png

2) Utility.java

import java.util.Scanner;

public class Utility 
{
    private static Scanner scanner = new Scanner(System.in);

    //给用户提供输入缓冲区,限制用户输入的长度。
    //如果输入长度不符合,则提示用户重新输入,并重新提供输入缓冲区;如果输入长度符合,则以字符串形式返回用户的输入。
    public static String readKeyBoard(int inputLength)
    {
        String inputStr = "";
        while (scanner.hasNextLine())
        {
            inputStr = scanner.nextLine();
            if (inputStr.length() <= inputLength)
            {
                break;
            }
            System.out.print("Invalid length of input! Please re-enter: ");
        }
        return inputStr;
    }

    //用于读入用户输入的界面菜单选择,限制用户输入有效选择,并返回有效的用户输入。
    public static char readMenuSelection()
    {
        char inputChar;
        while (true)
        {
            String inputStr = readKeyBoard(1);
            inputChar = inputStr.charAt(0);
            if (inputChar != '1' && inputChar != '2' && inputChar != '3' && inputChar != '4')
            {
                System.out.print("Invalid selection! Please re-enter: ");
            }
            else
            {
                break;
            }
        }
        return inputChar;
    }

    //用于读入用户输入的收入和支出金额,限制用户输入长度不超过4位的整数,并返回有效的用户输入。
    public static int readNumber()
    {
        int inputNumber;
        while(true)
        {
            String inputStr = readKeyBoard(4);
            try
            {
                inputNumber = Integer.parseInt(inputStr);
                break;
            }
            catch (NumberFormatException e)
            {
                System.out.print("Invalid input! Please re-enter: ");
            }
        }
        return inputNumber;
    }

    //用于读入用户输入的收入或支出的说明,限制用户输入长度不超过8的字符串,并返回有效的用户输入。
    public static String readString()
    {
        String inputStr = readKeyBoard(8);
        return inputStr;
    }

    //用于读入用户输入的确认,限制用户输入为'Y/y'或'N/n',并返回有效的用户输入。
    public static char readConfirmSelection()
    {
        char inputChar;
        while (true)
        {
            String inputStr = readKeyBoard(1);
            inputChar = inputStr.charAt(0);
            if (inputChar != 'Y' && inputChar != 'y' && inputChar != 'N' && inputChar != 'n')
            {
                System.out.print("Invalid input! Please re-enter: ");
            }
            else
            {
                break;
            }
        }
        return inputChar;
    }
}

3) FamilyAccount.java

  • step 1: 搭框架
  • step 2: 分别编码各个模块,实现各个模块的功能。
class FamilyAccount 
{
    public static void main(String[] args) 
    {
        boolean isFlag = true;
        String details = "";
        int accountBalance = 10000;
        while (isFlag)
        {
            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();
            System.out.print("                             请选择<1-4>:");

            char selection = Utility.readMenuSelection();

            switch(selection)
            {
                case '1':
                    System.out.println("\n----------------------当前收支明细记录------------------------");
                    System.out.println("收支\t\t账户金额\t\t收支金额\t\t说  明");
                    System.out.println();
                    System.out.println(details);
                    System.out.println("--------------------------------------------------------------");
                    System.out.println();
                    break;
                case '2':
                    System.out.print("本次收入金额:");
                    int income = Utility.readNumber();
                    System.out.print("本次收入说明:");
                    String incomeExplain = Utility.readString();
                    accountBalance += income;
                    details += ("\n收入\t\t" + accountBalance + "\t\t\t" + income + "\t\t\t" + incomeExplain);
                    System.out.println("\n登记完成!");
                    break;
                case '3':
                    System.out.print("本次支出金额:");
                    int expend = Utility.readNumber();
                    System.out.print("本次支出说明:");
                    String expendExplain = Utility.readString();
                    accountBalance -= expend;
                    details += ("\n支出\t\t" + accountBalance + "\t\t\t" + expend + "\t\t\t" + expendExplain);
                    System.out.println("\n登记完成!");
                    break;
                case '4':
                    System.out.print("确认是否退出<y/n>: ");
                    char confirmInput = Utility.readConfirmSelection();
                    if (confirmInput == 'y' || confirmInput == 'Y')
                    {
                        isFlag = false;
                    }
            }
        }
    }
}
Last Modified: October 27, 2023