概要
这是一个基于Java开发的个人记账管理系统,帮助用户记录日常收支情况,进行财务统计和分析。
项目结构设计
bash
AccountingApp/
├── src/main/java/com/accounting/
│ ├── model/
│ │ ├── Transaction.java # 交易记录实体类
│ │ └── Category.java # 分类实体类
│ ├── service/
│ │ └── AccountingService.java # 记账业务逻辑
│ ├── util/
│ │ └── DateUtil.java # 日期工具类
│ └── Main.java # 主程序入口
核心类实现
1. 交易记录实体类 (Transaction)
java
package com.accounting.model;
import java.time.LocalDateTime;
import java.math.BigDecimal;
public class Transaction {
private Long id;
private LocalDateTime date;
private BigDecimal amount;
private String type; // "income" or "expense"
private String category;
private String description;
// 构造函数
public Transaction() {}
public Transaction(BigDecimal amount, String type, String category, String description) {
this.amount = amount;
this.type = type;
this.category = category;
this.description = description;
this.date = LocalDateTime.now();
}
// Getter和Setter方法
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public LocalDateTime getDate() { return date; }
public void setDate(LocalDateTime date) { this.date = date; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getCategory() { return category; }
public void setCategory(String category) { this.category = category; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
@Override
public String toString() {
return String.format("[%s] %s: %.2f (%s) - %s",
date.toLocalDate(), type, amount, category, description);
}
}
2. 记账业务服务类 (AccountingService)
java
package com.accounting.service;
import com.accounting.model.Transaction;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class AccountingService {
private List<Transaction> transactions;
private Long nextId = 1L;
public AccountingService() {
this.transactions = new ArrayList<>();
}
/**
* 添加收入记录
*/
public void addIncome(BigDecimal amount, String category, String description) {
Transaction transaction = new Transaction(amount, "收入", category, description);
transaction.setId(nextId++);
transactions.add(transaction);
System.out.println("收入记录添加成功: " + transaction);
}
/**
* 添加支出记录
*/
public void addExpense(BigDecimal amount, String category, String description) {
Transaction transaction = new Transaction(amount, "支出", category, description);
transaction.setId(nextId++);
transactions.add(transaction);
System.out.println("支出记录添加成功: " + transaction);
}
/**
* 获取所有交易记录
*/
public List<Transaction> getAllTransactions() {
return new ArrayList<>(transactions);
}
/**
* 根据日期范围查询交易记录
*/
public List<Transaction> getTransactionsByDateRange(LocalDate startDate, LocalDate endDate) {
return transactions.stream()
.filter(t -> !t.getDate().toLocalDate().isBefore(startDate))
.filter(t -> !t.getDate().toLocalDate().isAfter(endDate))
.collect(Collectors.toList());
}
/**
* 计算总收入
*/
public BigDecimal getTotalIncome() {
return transactions.stream()
.filter(t -> "收入".equals(t.getType()))
.map(Transaction::getAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 计算总支出
*/
public BigDecimal getTotalExpense() {
return transactions.stream()
.filter(t -> "支出".equals(t.getType()))
.map(Transaction::getAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 计算账户余额
*/
public BigDecimal getBalance() {
return getTotalIncome().subtract(getTotalExpense());
}
/**
* 按分类统计支出
*/
public void printExpenseByCategory() {
System.out.println("\n=== 支出分类统计 ===");
transactions.stream()
.filter(t -> "支出".equals(t.getType()))
.collect(Collectors.groupingBy(
Transaction::getCategory,
Collectors.reducing(BigDecimal.ZERO, Transaction::getAmount, BigDecimal::add)))
.forEach((category, amount) ->
System.out.println(category + ": " + amount));
}
}
3. 主程序类 (Main)
java
package com.accounting;
import com.accounting.model.Transaction;
import com.accounting.service.AccountingService;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Scanner;
public class Main {
private static AccountingService accountingService = new AccountingService();
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("=== 个人记账软件 ===");
while (true) {
showMenu();
int choice = scanner.nextInt();
scanner.nextLine(); // 消费换行符
switch (choice) {
case 1:
addIncome();
break;
case 2:
addExpense();
break;
case 3:
showAllTransactions();
break;
case 4:
showStatistics();
break;
case 5:
showExpenseByCategory();
break;
case 0:
System.out.println("感谢使用,再见!");
return;
default:
System.out.println("无效选项,请重新选择");
}
}
}
private static void showMenu() {
System.out.println("\n========== 菜单 ==========");
System.out.println("1. 添加收入");
System.out.println("2. 添加支出");
System.out.println("3. 查看所有记录");
System.out.println("4. 查看统计信息");
System.out.println("5. 支出分类统计");
System.out.println("0. 退出");
System.out.print("请选择操作: ");
}
private static void addIncome() {
System.out.print("请输入收入金额: ");
BigDecimal amount = scanner.nextBigDecimal();
scanner.nextLine(); // 消费换行符
System.out.print("请输入收入分类 (如: 工资、奖金等): ");
String category = scanner.nextLine();
System.out.print("请输入备注: ");
String description = scanner.nextLine();
accountingService.addIncome(amount, category, description);
}
private static void addExpense() {
System.out.print("请输入支出金额: ");
BigDecimal amount = scanner.nextBigDecimal();
scanner.nextLine(); // 消费换行符
System.out.print("请输入支出分类 (如: 餐饮、交通、购物等): ");
String category = scanner.nextLine();
System.out.print("请输入备注: ");
String description = scanner.nextLine();
accountingService.addExpense(amount, category, description);
}
private static void showAllTransactions() {
List<Transaction> transactions = accountingService.getAllTransactions();
if (transactions.isEmpty()) {
System.out.println("暂无交易记录");
return;
}
System.out.println("\n=== 所有交易记录 ===");
transactions.forEach(System.out::println);
}
private static void showStatistics() {
System.out.println("\n=== 统计信息 ===");
System.out.println("总收入: " + accountingService.getTotalIncome());
System.out.println("总支出: " + accountingService.getTotalExpense());
System.out.println("账户余额: " + accountingService.getBalance());
}
private static void showExpenseByCategory() {
accountingService.printExpenseByCategory();
}
}
生成可运行程序:使用 IntelliJ IDEA 中文版导出可执行 JAR
-
打开项目结构
- 点击菜单栏 "文件" → "项目结构"
-
创建 Artifact
- 在左侧面板选择 "工件" (Artifacts)
- 点击 "+" 号 → "JAR" → "来自模块的依赖项"
- 选择 com.accounting.Main 类作为主类
- 点击 "确定"
-
构建 Artifact
- 点击菜单栏 "构建" → "构建工件"
- 选择刚刚创建的工件
- 点击 "构建"
-
找到生成的 JAR 文件
- 通常在项目根目录下的
out/artifacts文件夹中
- 通常在项目根目录下的
创建运行脚本
在生成的 JAR 文件同目录下创建 run.bat 文件:
batch
@echo off
java -jar AccountingApp-1.0.0.jar
pause
这样用户就可以通过双击 run.bat 来运行你的记账软件了。