在Java里如何开发控制台记账程序_Java记账项目完整示例

用Scanner+ArrayList实现记账核心:定义Transaction类含amount、type、note、timestamp字段;输入时统一用nextLine()防换行残留;查账用LocalDateTime时间比较而非字符串匹配;退出时用Files.write按行存文本,分隔符为|。

用 Scanner + ArrayList 做最简记账核心

控制台记账程序不需要框架,Java 标准库完全够用。关键不是“怎么炫技”,而是把 收支类型金额备注时间 四个字段稳稳存住、查得快、删得准。

别一上来就搞数据库或文件持久化——先用 ArrayList 在内存里跑通流程。定义一个 Transaction 类,至少包含:

  • double amount(别用 float,精度问题会出错)
  • String type(建议固定为 "income""expense"
  • String note
  • LocalDateTime timestamp(用 java.time,别用过时的 Date

用户输入用 Scanner 逐行读取,注意调用 scanner.nextLine() 消掉换行残留,否则后续 nextLine() 会跳过输入。

避免 Scanner.nextLine() 吃掉输入的坑

这是新手写控制台程序最常卡住的地方:用 scanner.nextDouble()scanner.nextInt() 读完数字后,紧接着 scanner.nextLine() 会立刻返回空字符串——因为前一个方法没消费掉回车符。

解决办法统一加一行“清缓存”:

scanner.nextDouble();
scanner.nextLine(); // ← 必须加这一行
String note = scanner.nextLine();

更稳妥的做法是全程只用 nextLine(),再手动解析数字:

String amountStr = scanner.nextLine();
double amount = Double.parseDouble(amountStr); // 加 try-catch 处理异常

这样逻辑一致,不易漏。

按日期范围查账单时别手写字符串比较

用户说“查 2025-03-01 到 2025-03-15 的支出”,如果把 timestamp.toString() 当成字符串去 containssubstring 截取,会出错且难维护。

正确做法是用 LocalDateTime 的时间比较能力:

LocalDateTime start = LocalDate.parse("2025-03-01").atStartOfDay();
LocalDateTime end = LocalDate.parse("2025-03-15").plusDays(1).atStartOfDay();

for (Transaction t : records) {
    if (t.timestamp.isAfter(start) && t.timestamp.isBefore(end)) {
        System.out.println(t);
    }
}

注意:用 isBefore/isAfter 而非 ,避免毫秒级误差;结束时间设为次日 0 点,才能包含 3 月 15 日全天。

退出前把数据存到文件,但别用 FileWriter 直接写对象

程序退出时把 ArrayList 存成文件,目的是下次启动还能读。别用 FileWriter 拼 JSON 或 CSV 字符串——容易格式错乱、中文乱码、字段含逗号就崩。

推荐方案:用 ObjectOutputStream 序列化(仅限开发练手),或更实用的 Files.write() 写纯文本行:

List lines = records.stream()
    .map(t -> String.format("%s|%s|%.2f|%s", 
        t.timestamp, t.type, t.amount, t.note))
    .collect(Collectors.toList());
Files.write(Paths.get("ledger.txt"), lines, StandardCharsets.UTF_8);

读的时候用 Files.readAllLines() + String.split("\\|") 解析。分隔符选 | 比逗号安全,但注意 note 里如果真有 |,就得换成更少见的符号(比如 \u0001)或改用 Jackson 写 JSON。

真正上线项目肯定要 SQLite 或 H2,但控制台练手阶段,文件按行存是最可控、最容易调试的方式。