iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
自我挑戰組

Java 程式設計與實作:30 天打造個人記帳系統系列 第 17 篇

記帳系統實作:依照消費分類統計金額

  • 分享至 

  • xImage
  •  

昨天完成了「總支出統計」功能,可以把所有消費金額加起來。

例如:

早餐|60 元|飲食
午餐|120 元|飲食
捷運|30 元|交通

程式可以算出:

總支出:210 元

但只有總金額其實還不太夠,因為我還想知道:

我的錢到底花到哪裡去了?

所以 Day 17 要加入「分類支出統計」,讓程式分別計算飲食、交通、購物和娛樂花了多少錢。

今天想完成的功能

原本的主選單是:

===== 個人記帳系統 =====

  1. 新增消費
  2. 查看紀錄
  3. 查看總支出
  4. 離開

今天增加一個功能:

===== 個人記帳系統 =====

  1. 新增消費
  2. 查看紀錄
  3. 查看總支出
  4. 分類支出統計
  5. 離開

假設目前有:

  1. 早餐|60 元|飲食
  2. 午餐|120 元|飲食
  3. 捷運|30 元|交通
  4. 電影|300 元|娛樂

我希望選擇功能 4 之後得到:

===== 分類支出統計 =====
飲食:180 元
交通:30 元
購物:0 元
娛樂:300 元

第一步:準備不同分類的總金額

首先建立四個變數:

int foodTotal = 0;
int transportTotal = 0;
int shoppingTotal = 0;
int entertainmentTotal = 0;

分別代表:

foodTotal → 飲食
transportTotal → 交通
shoppingTotal → 購物
entertainmentTotal → 娛樂

一開始還沒有計算,所以全部都是 0。

第二步:逐筆查看消費紀錄

我們的消費資料都放在:

ArrayList expenses

所以可以使用 for:

for (int i = 0; i < expenses.size(); i++) {
Expense expense = expenses.get(i);
}

這樣就可以把每一筆消費拿出來檢查。

第三步:判斷消費分類

接著取得這筆消費的分類:

expense.getCategory()

例如可能得到:

飲食
交通
購物
娛樂

然後使用 switch:

switch (expense.getCategory()) {
case "飲食":
foodTotal += expense.getAmount();
break;
case "交通":
transportTotal += expense.getAmount();
break;
case "購物":
shoppingTotal += expense.getAmount();
break;
case "娛樂":
entertainmentTotal += expense.getAmount();
break;
}

假設目前讀到:

午餐|120 元|飲食

就會執行:

foodTotal += expense.getAmount();

也就是:

foodTotal = foodTotal + 120

計算過程

假設紀錄是:

早餐|60 元|飲食
捷運|30 元|交通
午餐|120 元|飲食
電影|300 元|娛樂

程式會依序計算:

早餐 → 飲食
foodTotal = 0 + 60 = 60
捷運 → 交通
transportTotal = 0 + 30 = 30
午餐 → 飲食
foodTotal = 60 + 120 = 180
電影 → 娛樂
entertainmentTotal = 0 + 300 = 300

最後:

飲食:180 元
交通:30 元
購物:0 元
娛樂:300 元

這就是今天功能的核心。

建立 categoryStatistics() Method

和之前一樣,我想把這個功能獨立成 Method:

public static void categoryStatistics() {
int foodTotal = 0;
int transportTotal = 0;
int shoppingTotal = 0;
int entertainmentTotal = 0;
for (int i = 0; i < expenses.size(); i++) {
Expense expense = expenses.get(i);
switch (expense.getCategory()) {
case "飲食":
foodTotal += expense.getAmount();
break;
case "交通":
transportTotal += expense.getAmount();
break;
case "購物":
shoppingTotal += expense.getAmount();
break;
case "娛樂":
entertainmentTotal += expense.getAmount();
break;
}
}
System.out.println("飲食:" + foodTotal + " 元");
System.out.println("交通:" + transportTotal + " 元");
System.out.println("購物:" + shoppingTotal + " 元");
System.out.println("娛樂:" + entertainmentTotal + " 元");
}

之後只需要:

categoryStatistics();

就可以執行分類統計。

順便改善「新增消費」

之前新增消費時,是讓使用者自己輸入:

請輸入消費分類:飲食

但如果不小心輸入:

飲時

或:

吃飯

程式就不知道它應該屬於「飲食」。

所以今天順便把分類改成選單:

請選擇消費分類:

  1. 飲食
  2. 交通
  3. 購物
  4. 娛樂

然後使用 switch:

String category;
switch (categoryChoice) {
case 1:
category = "飲食";
break;
case 2:
category = "交通";
break;
case 3:
category = "購物";
break;
case 4:
category = "娛樂";
break;
default:
category = "其他";
}

這樣資料會比較統一。

Day 17 完整程式

import java.util.Scanner;
import java.util.ArrayList;
import java.util.InputMismatchException;
class Expense {
private String item;
private int amount;
private String category;
Expense(String item, int amount, String category) {
this.item = item;
this.amount = amount;
this.category = category;
}
public String getItem() {
return item;
}
public int getAmount() {
return amount;
}
public String getCategory() {
return category;
}
}
public class Main {
static Scanner scanner = new Scanner(System.in);
static ArrayList expenses = new ArrayList<>();
public static void main(String[] args) {
boolean running = true;
while (running) {
showMenu();
try {
System.out.print("請選擇功能:");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
addExpense();
break;
case 2:
showExpenses();
break;
case 3:
calculateTotal();
break;
case 4:
categoryStatistics();
break;
case 5:
running = false;
System.out.println("已離開個人記帳系統!");
break;
default:
System.out.println("沒有這個選項!");
}
} catch (InputMismatchException e) {
System.out.println("輸入錯誤,請輸入數字!");
scanner.nextLine();
}
}
scanner.close();
}
public static void showMenu() {
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. 離開");
}
public static void addExpense() {
System.out.println();
System.out.println("===== 新增消費 =====");
System.out.print("請輸入消費項目:");
String item = scanner.nextLine();
try {
System.out.print("請輸入消費金額:");
int amount = scanner.nextInt();
System.out.println();
System.out.println("請選擇消費分類:");
System.out.println("1. 飲食");
System.out.println("2. 交通");
System.out.println("3. 購物");
System.out.println("4. 娛樂");
System.out.print("請輸入選項:");
int categoryChoice = scanner.nextInt();
scanner.nextLine();
String category;
switch (categoryChoice) {
case 1:
category = "飲食";
break;
case 2:
category = "交通";
break;
case 3:
category = "購物";
break;
case 4:
category = "娛樂";
break;
default:
category = "其他";
}
Expense expense =
new Expense(item, amount, category);
expenses.add(expense);
System.out.println("記帳成功!");
} catch (InputMismatchException e) {
System.out.println("輸入錯誤,請輸入數字!");
scanner.nextLine();
}
}
public static void showExpenses() {
System.out.println();
System.out.println("===== 消費紀錄 =====");
if (expenses.size() == 0) {
System.out.println("目前沒有消費紀錄。");
} else {
for (int i = 0; i < expenses.size(); i++) {
Expense expense = expenses.get(i);
System.out.println(
(i + 1) + ". "
+ expense.getItem()
+ "|" + expense.getAmount() + " 元"
+ "|" + expense.getCategory()
);
}
}
}
public static void calculateTotal() {
System.out.println();
System.out.println("===== 支出統計 =====");
if (expenses.size() == 0) {
System.out.println("目前沒有消費紀錄。");
return;
}
int total = 0;
for (int i = 0; i < expenses.size(); i++) {
total += expenses.get(i).getAmount();
}
System.out.println(
"目前共有 " + expenses.size() + " 筆消費"
);
System.out.println("總支出:" + total + " 元");
}
public static void categoryStatistics() {
System.out.println();
System.out.println("===== 分類支出統計 =====");
if (expenses.size() == 0) {
System.out.println("目前沒有消費紀錄。");
return;
}
int foodTotal = 0;
int transportTotal = 0;
int shoppingTotal = 0;
int entertainmentTotal = 0;
for (int i = 0; i < expenses.size(); i++) {
Expense expense = expenses.get(i);
switch (expense.getCategory()) {
case "飲食":
foodTotal += expense.getAmount();
break;
case "交通":
transportTotal += expense.getAmount();
break;
case "購物":
shoppingTotal += expense.getAmount();
break;
case "娛樂":
entertainmentTotal += expense.getAmount();
break;
}
}
System.out.println("飲食:" + foodTotal + " 元");
System.out.println("交通:" + transportTotal + " 元");
System.out.println("購物:" + shoppingTotal + " 元");
System.out.println("娛樂:" + entertainmentTotal + " 元");
}
}

實際執行結果

假設我新增四筆資料:

  1. 早餐|60 元|飲食
  2. 捷運|30 元|交通
  3. 午餐|120 元|飲食
  4. 電影|300 元|娛樂

現在主選單選擇:

請選擇功能:4

程式顯示:

===== 分類支出統計 =====
飲食:180 元
交通:30 元
購物:0 元
娛樂:300 元

如果選擇「查看總支出」:

===== 支出統計 =====
目前共有 4 筆消費
總支出:510 元

這樣就可以同時看到「總共花多少」以及「錢花在哪些地方」。

今天又用到了 switch

switch 是 Day 5 學過的內容。

當時只是做簡單的分類選單,現在重新使用:

switch (expense.getCategory())

已經變成真正的資料統計功能。

這也讓我發現前面學過的基礎語法,後面其實會一直重複用到。

今天還認識了 return

今天的程式有:

if (expenses.size() == 0) {
System.out.println("目前沒有消費紀錄。");
return;
}

這裡的:

return;

代表直接結束目前這個 Method。

例如沒有任何消費紀錄,就不需要繼續執行下面的統計程式。

可以簡單理解:

沒有紀錄
↓
顯示提示
↓
return
↓
結束這個 Method

Day 17 學習心得

今天替記帳系統加入了分類支出統計功能,可以分別計算飲食、交通、購物和娛樂的支出。

昨天只能知道自己總共花了多少錢,今天則可以進一步知道錢主要花在哪一類。我覺得做到這裡,記帳系統開始真的有「記帳」的感覺,而不是單純把資料輸入再顯示出來。

今天也再次使用了之前學過的 for、switch、ArrayList、Method 和 Object。以前單獨學這些語法時不知道之後可以拿來做什麼,現在慢慢把它們組合起來後,比較能理解每個語法實際使用的情境。


上一篇
記帳系統實作:加入「總支出統計」功能
下一篇
記帳系統實作:新增「刪除消費紀錄」功能
系列文
Java 程式設計與實作:30 天打造個人記帳系統 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言