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
相关产品推荐
相关产品推荐

