You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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());
        }
    }
}

关键逻辑说明

  1. Sale对象存入动态数组:

    • 读取文件每行后,按分号分割为姓名、设备类型、价格、日期四个字段
    • 将字段解析为Sale类所需的参数(转换设备字符串为枚举、处理价格格式、解析日期)
    • 创建Sale实例后,调用salesList.add()直接加入动态数组
  2. 计算各设备总营收:

    • 使用Map<DeviceType, Double>统计,遍历Sale列表时,以设备类型为key,累加对应价格
    • 这种方式无需修改代码即可适配新增的设备类型,比switch更灵活

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:36:17