够用但仅限单机玩具级场景;需用BigDecimal防精度丢失、重写toString便于调试、选JSON而非ObjectOutputStream持久化、HSQLDB比MySQL更适配轻量需求。

用 ArrayList 存交易记录够不够用?
够,但只适合单机、无持久化、不关心历史回溯的玩具级记账。每次重启程序,所有数据就清空。如果你只是想练手对象建模或理解 Account、Transaction 类怎么设计,ArrayList 是最轻量的起点。
注意别把金额用 float 或 double 存——会出现 0.1 + 0.2 != 0.3 这类问题。一律用 BigDecimal,哪怕多写几行 new BigDecimal("12.50")。
常见错误:直接用 System.out.println(list) 查数据,结果看到一串 Transaction@1a2b3c。记得重写 toString() 方法,否则调试时根本看不出哪笔是支出、哪笔是餐饮。
想保存数据到文件,该选 ObjectOutputStream 还是 JSON?
选 JSON(比如用 com.fasterxml.jackson.databind.ObjectMapper)。ObjectOutputStream 生成的是 Java 专属二进制,换 JDK 版本或改个字段类型就可能反序列化失败,而且没法用文本编辑器打开检查数据是否写对了。
立即学习“Java免费学习笔记(深入)”;
用 Jackson 更稳妥:
-
ObjectMapper默认不序列化null字段,避免配置项干扰 - 加
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")能统一时间格式 - 文件损坏时,JSON 至少能肉眼看出哪一行出错;而
.ser文件坏了一字节,整个读取就抛StreamCorruptedException
示例写法:
mapper.writeValue(new File("records.json"), transactionList);
要不要上数据库?从 HSQLDB 开始最省事
要,只要你想让数据跨会话保留、支持按日期查、做余额统计,文件方案很快会力不从心。但别一上来就配 MySQL——本地开发还要装服务、建库、管账号密码,纯增加阻塞点。
HSQLDB 是嵌入式数据库,一个 JAR 包搞定,数据默认存成几个 .script 和 .data 文件,关掉程序也不丢。建表语句也简单:
CREATE TABLE transactions ( id IDENTITY, amount DECIMAL(12,2), type VARCHAR(10), -- 'INCOME' or 'EXPENSE' category VARCHAR(20), time TIMESTAMP );
注意:HSQLDB 的 DECIMAL 对应 Java 的 BigDecimal,ResultSet 取值必须用 getBigDecimal("amount"),不能用 getDouble(),否则精度又丢了。
余额计算总出错?别在 UI 层累加,交给 SQL 或集合流
用户删了一笔收入,你如果在界面上维护一个全局 currentBalance 变量,再手动加减,很容易不同步。正确做法是每次需要显示余额时,重新算:
- 用数据库:执行
SELECT SUM(CASE WHEN type='INCOME' THEN amount ELSE -amount END) FROM transactions - 用内存列表:用
transactions.stream().mapToDouble(t -> t.getType() == INCOME ? t.getAmount().doubleValue() : -t.getAmount().doubleValue()).sum()(注意这里 double 只用于展示,计算过程仍用BigDecimal累加)
容易被忽略的一点:时间范围筛选。用户问“本月支出”,得用 LocalDateTime.now().withDayOfMonth(1) 构造起始时间,而不是硬写 "2024-06-01" ——下个月代码就失效。










