Java库存程序开发求助:销售对象存储与设备营收计算
解决方案
一、先完善你的Sale类
现有Sale类缺少必要的属性初始化和访问方法,需要补充设备类型、日期属性,以及对应的构造器和getter:
public class Sale { private String customerName; private DeviceType deviceType; private double price; private LocalDate saleDate; // 设备类型枚举 public enum DeviceType { SMARTPHONE, TABLET, LAPTOP; // 从文件字符串转换为枚举的静态方法 public static DeviceType fromString(String deviceStr) { return switch (deviceStr.trim().toLowerCase()) { case "智能手机" -> SMARTPHONE; case "平板" -> TABLET; case "笔记本" -> LAPTOP; default -> throw new IllegalArgumentException("未知设备类型: " + deviceStr); }; } } // 自定义日期类,补充带参数构造器和解析方法 public static class LocalDate { private int day; private int month; private int year; public LocalDate(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } // 从日期字符串解析为LocalDate的静态方法 public static LocalDate fromString(String dateStr) { String[] parts = dateStr.split("/"); if (parts.length != 3) { throw new IllegalArgumentException("日期格式错误: " + dateStr); } int day = Integer.parseInt(parts[0]); int month = Integer.parseInt(parts[1]); int year = Integer.parseInt(parts[2]); return new LocalDate(day, month, year); } } // 完整的Sale构造器 public Sale(String customerName, DeviceType deviceType, double price, LocalDate saleDate) { this.customerName = customerName; this.deviceType = deviceType; this.price = price; this.saleDate = saleDate; } // 用于统计的getter方法 public DeviceType getDeviceType() { return deviceType; } public double getPrice() { return price; } }
二、修正主程序,将文件数据转为Sale对象存入动态数组
修改主类的文件读取逻辑,替换固定路径为用户输入的文件名,同时将每行数据解析为Sale对象存入ArrayList<Sale>:
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Scanner; public class InventoryProgram { public static void main(String[] args) { Scanner in = new Scanner(System.in); File targetFile = null; // 循环获取有效文件名 while (targetFile == null || !targetFile.exists()) { System.out.println("请输入文件名:"); String input = in.nextLine().trim(); targetFile = new File(input); if (!targetFile.exists()) { System.out.println("文件不存在,请重新输入!"); } } System.out.println("文件已找到。"); // 存储Sale对象的动态数组 ArrayList<Sale> salesList = new ArrayList<>(); // 读取文件并解析为Sale对象 try (BufferedReader br = new BufferedReader(new FileReader(targetFile))) { String line; while ((line = br.readLine()) != null) { line = line.trim(); if (line.isEmpty()) continue; // 跳过空行 // 按分号分割字段 String[] fields = line.split(";"); if (fields.length != 4) { System.out.println("无效的行格式,跳过: " + line); continue; } try { // 解析每个字段 String customerName = fields[0].trim(); Sale.DeviceType deviceType = Sale.DeviceType.fromString(fields[1].trim()); // 处理价格的逗号转点,转换为double double price = Double.parseDouble(fields[2].trim().replace(",", ".")); Sale.LocalDate saleDate = Sale.LocalDate.fromString(fields[3].trim()); // 创建Sale对象并加入动态数组 salesList.add(new Sale(customerName, deviceType, price, saleDate)); } catch (Exception e) { System.out.println("解析行失败: " + line + ",错误信息: " + e.getMessage()); } } } catch (IOException e) { System.out.println("读取文件时出错: " + e.getMessage()); return; } System.out.println("共解析 " + salesList.size() + " 条销售记录"); // 计算并打印各设备类型总营收 calculateDeviceRevenue(salesList); } // 计算各设备总营收的方法 private static void calculateDeviceRevenue(ArrayList<Sale> salesList) { // 用Map存储每个设备类型的总营收(更灵活的方式) java.util.Map<Sale.DeviceType, Double> revenueMap = new java.util.HashMap<>(); for (Sale sale : salesList) { Sale.DeviceType type = sale.getDeviceType(); revenueMap.put(type, revenueMap.getOrDefault(type, 0.0) + sale.getPrice()); } // 打印结果,保留两位小数 System.out.println("\n各设备类型总营收:"); for (java.util.Map.Entry<Sale.DeviceType, Double> entry : revenueMap.entrySet()) { System.out.printf("%s: %.2f\n", entry.getKey(), entry.getValue()); } } }
关键逻辑说明
Sale对象存入动态数组:
- 读取文件每行后,按分号分割为姓名、设备类型、价格、日期四个字段
- 将字段解析为
Sale类所需的参数(转换设备字符串为枚举、处理价格格式、解析日期) - 创建
Sale实例后,调用salesList.add()直接加入动态数组
计算各设备总营收:
- 使用
Map<DeviceType, Double>统计,遍历Sale列表时,以设备类型为key,累加对应价格 - 这种方式无需修改代码即可适配新增的设备类型,比switch更灵活
- 使用
内容的提问来源于stack exchange,提问作者katerina
相关产品推荐
相关产品推荐

