天天看點

徒手撸一個記賬本(附源碼)

前言

之前已經寫過關于 學生成績管理系統 以及 點菜系統 的文章,大家如果感興趣,可以點選各自的傳送門去看看呀!

接下來開始我們今天的正題,我們日常生活中,想必有很多人都有記賬的習慣,那今天,我們就來看看,如何設計并實作一個記賬本。

需求分析

打開我們手機裡的記賬本,可以發現主要提供如下幾個功能:

  1. 添加賬目
  2. 删除賬目
  3. 修改賬目
  4. 查詢賬目
    • 查詢所有賬目
    • 按時間區間查詢
    • 按賬目類型查詢
  5. 退出記賬本
徒手撸一個記賬本(附源碼)

功能預覽及代碼實作

主菜單

主菜單中,主要用于列印提示我們進行選擇,然後根據我們的輸入再進入不同的子功能子產品中。

  • 預覽
徒手撸一個記賬本(附源碼)
  • 代碼實作

代碼實作很簡單,隻需要列印出提示資訊即可,之後後續輸入以及進入不同子功能子產品,我們可以使用

switch

來進行選擇。

package com.cunyu;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 *
 * @author : 村雨
 * @version : 1.0
 * @project : Java 實戰
 * @package : com.cunyu
 * @className : MainApp
 * @createTime : 2021/8/1 7:22
 * @email : [email protected]
 * @公衆号 : 村雨遙
 * @website : https://cunyu1943.github.io
 * @description :
 */
public class MainApp {
    
    public static void main(String[] args) {

        boolean flag = true;
        while (flag) {
            System.out.println("----------歡迎使用記賬系統--------");
            System.out.println("----------【1】添加賬務----------");
            System.out.println("----------【2】删除賬務----------");
            System.out.println("----------【3】修改賬務----------");
            System.out.println("----------【4】查詢賬務----------");
            System.out.println("----------【0】退出-------------");
            System.out.println("請輸入功能序号【0-4】");
        }
        System.out.println("退出系統,期待下次見面 ~");
    }
}

           

當我們需要添加一筆新的賬目時,此時就可以進入 添加賬目 子子產品,這裡的功能主要是根據我們自己輸入的 ID、類别、賬戶、類型、金額、時間以及備注将其添加到我們的總賬目清單中進行彙總。

徒手撸一個記賬本(附源碼)

要實作添加功能也很簡單,根據我們的輸入,我們利用賬目類的構造函數建立一個對象,然後将其加入總賬目清單當中就可以了。

public void add(List<Bill> billList, int id, String category, String account, String type, double amount, String time, String desc) {
    //建立一個賬單對象,然後将其加入清單
    Bill bill = new Bill(id, category, account, type, amount, time, desc);
    billList.add(bill);
}
           

假如我們的賬目要公開給别人看,而自己有的賬目又不想讓别人看到,咋辦呢?很簡單!我們隻需要将這筆賬目幹掉即可!這裡我們隻要輸入我們所要删除的賬單 ID,然後将其從總賬目清單中删除即可。

徒手撸一個記賬本(附源碼)

要删除我們的賬目,隻需要根據我們輸入的賬單 id,找到對應 id 的賬目,然後将其删除即可,這裡之是以沒有使用

remove(index)

的方式,是因為我們的 id 是自己輸入的,這其實是不規則的,如果我們使用

remove(index)

的方式,就有可能導緻越界的問題。

public void del(List<Bill> billList, int id) {
    //找到對應 id 的賬單,并将其删除
    for (Bill bill : billList) {
        if (bill.getId() == id) {
            billList.remove(bill);
        }
    }
}
           

我們偷偷拿了私房錢買了猛男必備顯示卡(RTX 3090)想趁空了打打遊戲,遇到老婆查賬時,這時候可不能慌,我們隻需要把賬單偷梁換柱,改換成其他東西就可以,而且此事神不知鬼不覺,美滋滋呀!

徒手撸一個記賬本(附源碼)

利用代碼實作也很簡單,找到對應 ID 的賬單,然後重新輸入賬單各個細節進行修改即可!

public void modify(List<Bill> billList) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("輸入你要修改對應賬務的 ID");
    int id = scanner.nextInt();

    System.out.println("請輸入修改後的賬務類别");
    String category = scanner.next();

    System.out.println("請輸入修改後的賬戶");
    String account = scanner.next();

    System.out.println("請輸入修改後的類型(收入/支出)");
    String type = scanner.next();

    System.out.println("請輸入修改後的金額");
    double amount = scanner.nextDouble();

    System.out.println("請輸入修改後的時間");
    String time = scanner.next();

    System.out.println("請輸入修改後的備注");
    String description = scanner.next();
    //找到對應 id 的賬單,然後修改對應資訊
    for (Bill bill : billList) {

        if (bill.getId() == id) {

            bill.setCategory(category);
            bill.setAmount(amount);
            bill.setAccount(account);
            bill.setTime(time);
            bill.setType(type);
            bill.setDesc(description);
        }
    }

}
           

查詢賬目這裡,我們又分為 3 個不同的功能,既可以檢視所有賬單,也可以根據我們所輸入的時間區間進行篩選,最後,還能夠根據我們的輸入查詢出收入和支出的詳細情況。

徒手撸一個記賬本(附源碼)

查詢所有賬單很簡單,隻需要周遊我們總賬單清單即可。

public void queryAll(List<Bill> billList) {
    System.out.println("ID\t\t類别\t\t\t賬戶\t\t類型\t\t金額\t\t\t時間\t\t\t\t備注");
    for (Bill bill : billList) {
        System.out.println(bill.getId() + "\t\t" + bill.getCategory() + "\t\t" + bill.getAccount() + "\t\t" + bill.getType() + "\t\t" + bill.getAmount() + "\t\t" + bill.getTime() + "\t\t" + bill.getDesc());
    }
}
           

徒手撸一個記賬本(附源碼)

按照時間跨度來查詢稍微要麻煩一些,這裡要處理兩個輸入,一個是開始時間,一個是結束時間,我們需要将賬單的時間和這兩個時間進行比較,篩選出介于這兩者之間的賬單。是以這裡要涉及到

Date

類,然後就是如何從總賬單清單中過濾出滿足時間跨度的賬單。

public void queryByTime(List<Bill> billList, String startTime, String endTime) {
    // 時間格式化
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    List<Bill> bills = billList.stream().filter(bill -> {
        String tmpTime = bill.getTime();
        try {
            // 将輸入的時間字元串轉換為格式化的 Date 類型
            Date tmpDate = simpleDateFormat.parse(tmpTime);
            Date startDate = simpleDateFormat.parse(startTime);
            Date endDate = simpleDateFormat.parse(endTime);
            // 将介于開始時間和結束時間的賬單進行過濾
            if (tmpDate.before(endDate) && tmpDate.after(startDate)) {
                return true;
            }
        } catch (ParseException parseException) {
            parseException.printStackTrace();
        }
        return false;
        //    将其轉換為清單
    }).collect(Collectors.toList());

    queryAll(bills);
}
           

按類型查詢

徒手撸一個記賬本(附源碼)

這裡按類型查詢其實就是在查詢所有賬單的基礎上加上一個限制條件,隻要其類型等于我們的輸入即可,這裡我寫了兩種篩選的方法。一種是直接使用

if

語句進行過濾,而另一種則是同按時間跨度一樣使用集合的

Stream

流來進行過濾。

public void queryByType(List<Bill> billList, String type) {
    //1. 第一種方式,利用條件判斷
    //for (Bill bill : billList) {
    //    if (bill.getType().equals(type)) {
    //        System.out.println(bill.getId() + "\t\t" + bill.getCategory() + "\t\t" + bill.getAccount() + "\t\t" + bill.getType() + "\t\t" + bill.getAmount() + "\t\t" + bill.getTime() + "\t\t" + bill.getDesc());
    //    }
    //}

    //2. 第二種方式,利用集合 Stream 流
    List<Bill> bills = billList.stream().filter(bill -> {
        String tmpType = bill.getType();
        return tmpType.equals(type);
    }).collect(Collectors.toList());
    queryAll(bills);
}
           

退出系統

徒手撸一個記賬本(附源碼)

在主菜單中,我們已經設定了一個标志位

flag

,當

flag

true

時,我們每完成一項功能則循環列印主菜單在控制台中,而如果我們想要退出系統,隻需要将标志位

flag

設定為

false

即可,此時不滿足

while

循環的條件,是以跳出循環,是以退出系統的關鍵在于标志位狀态的轉換。

case "0":
    flag = false;
    break;
           

整體程式

将各個子子產品功能實作之後,剩下的就是整合工作了,最後得到我們最後的總體程式結構如下,主要代碼均位于

com.cunyu

包下,然後分别是:

  • 實體類

    Bill

  • 接口類

    IBill

  • 主程式

    MainApp

總結