昨天完成了「總支出統計」功能,可以把所有消費金額加起來。
例如:
早餐|60 元|飲食
午餐|120 元|飲食
捷運|30 元|交通
程式可以算出:
總支出:210 元
但只有總金額其實還不太夠,因為我還想知道:
我的錢到底花到哪裡去了?
所以 Day 17 要加入「分類支出統計」,讓程式分別計算飲食、交通、購物和娛樂花了多少錢。
今天想完成的功能
原本的主選單是:
===== 個人記帳系統 =====
今天增加一個功能:
===== 個人記帳系統 =====
假設目前有:
我希望選擇功能 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();
就可以執行分類統計。
順便改善「新增消費」
之前新增消費時,是讓使用者自己輸入:
請輸入消費分類:飲食
但如果不小心輸入:
飲時
或:
吃飯
程式就不知道它應該屬於「飲食」。
所以今天順便把分類改成選單:
請選擇消費分類:
然後使用 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 + " 元");
}
}
實際執行結果
假設我新增四筆資料:
現在主選單選擇:
請選擇功能: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。以前單獨學這些語法時不知道之後可以拿來做什麼,現在慢慢把它們組合起來後,比較能理解每個語法實際使用的情境。