You need to enable JavaScript to run this app. Java Grocery项目产品编码重复校验与文件写入实现咨询
优惠活动
大模型
产品
解决方案
定价
更多

Java Grocery项目产品编码重复校验与文件写入实现咨询

杂货商品管理系统产品编码重复校验逻辑修正

核心需求

输入产品编码时提前校验,编码已存在于grocery.txt则不允许重复写入,仅编码不存在时才执行文件写入操作。

当前代码存在的问题

  • 流初始化逻辑存在文件访问冲突:try块内同时初始化了追加模式的FileWriter和读取文件的BufferedReader,两类流同时打开会触发文件锁定异常,且逻辑上无需在写入分支同时挂载两个读写通道
  • 重复校验逻辑完全失效:adminObject1是全局复用对象,遍历文件时每一行都会覆盖它的产品编码属性,整轮遍历结束后,adminObject1中存储的永远是文件最后一行的产品编码,无法识别前面所有行的重复编码
  • 全局缓存存在数据污染:groceryRecord全局集合在每次进入添加分支时没有做清空操作,会重复累加文件中的所有历史数据,造成内存浪费
  • 文件写入存在硬编码错误:写入行的最后一个字段本该记录折扣值getDiscount(),实际误写为数量值getQuantity(),长期运行会导致文件存储的折扣数据和数量完全一致,后续读取解析时出现数据错位

修正后的核心代码

// 用HashSet存储所有已存在的产品编码,重复查询效率为O(1)
Set<Integer> existingProductCodeSet = new HashSet<>();

// 第一阶段:先单独执行文件读取校验,读完自动关闭读流
try (BufferedReader reader = new BufferedReader(new FileReader("grocery.txt"))) {
    String currentLine;
    // 每次读取前先清空历史缓存的商品记录
    groceryRecord.clear();
    while ((currentLine = reader.readLine()) != null) {
        if (currentLine.isBlank()) continue;
        String[] groceryDetail = currentLine.split(",");
        int existCode = Integer.parseInt(groceryDetail[0]);
        // 收集所有已存在的产品编码
        existingProductCodeSet.add(existCode);
        // 原有读取商品明细的逻辑保留
        adminObject1.setProductCode(existCode);
        adminObject1.setName(groceryDetail[1]);
        adminObject1.setPrice(Double.parseDouble(groceryDetail[2]));
        adminObject1.setQuantity(Double.parseDouble(groceryDetail[3]));
        adminObject1.setTax(Double.parseDouble(groceryDetail[4]));
        adminObject1.setDiscount(Double.parseDouble(groceryDetail[5]));
        groceryRecord.add(new Grocery(
            adminObject1.getProductCode(),
            adminObject1.getName(),
            adminObject1.getPrice(),
            adminObject1.getQuantity(),
            adminObject1.getTax(),
            adminObject1.getDiscount()
        ));
    }
}

// 第二阶段:执行重复校验
if (existingProductCodeSet.contains(adminObject.getProductCode())) {
    System.out.println("Duplicate Product Code.. Please re-enter");
} else {
    // 第三阶段:校验通过后,单独打开追加写流写入数据
    try (BufferedWriter groceryFile = new BufferedWriter(new FileWriter("grocery.txt", true))) {
        // 修正之前写错字段的硬编码问题
        groceryFile.write(String.format(
            "%d,%s,%.2f,%.2f,%.2f,%.2f%n",
            adminObject.getProductCode(),
            adminObject.getName(),
            adminObject.getPrice(),
            adminObject.getQuantity(),
            adminObject.getTax(),
            adminObject.getDiscount()
        ));
        System.out.println("商品数据已保存成功");
    }
}

注意事项

  • 读写同一文件时必须遵循先读、再校验、最后写的顺序,严禁同时打开读写两类流,避免文件占用异常
  • 遍历文件做校验时,需把所有遍历到的目标值存入独立集合,不能仅靠循环结束后的临时变量做判断
  • 全局复用的对象、集合在每次使用前必须重置状态,避免上一轮的残留数据干扰当前业务逻辑

内容的提问来源于stack exchange,提问作者nekim321

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 05:54:04