用Java语言编写一个库房出入货物程序设计,要对华为和小米两种手机产品进行入库,要求编写一个模拟商品入库的程序,可以在控制台输入入库商品的数量,最后打印出仓库中所有商品详细信息以及所有商品的总库存数和库存商品总金额。 商品信息如下: 品牌型号:华为,小米 尺寸:5.5,5.0 价格:3688.88,2988.88 配置:8+128G 全面刘海屏,4+64G 全面屏 入库:2,3 总价:7377.76,8966.64

时间: 2025-07-06 11:35:08 浏览: 4
<think>嗯,用户希望用Java编写一个库房出入货物程序,主要是针对华为和小米两种手机的入库操作。需要在控制台输入数量,然后输出详细信息、总库存和总金额。首先,我得分析用户的需求,确保程序结构合理,符合面向对象的设计。 首先,商品信息包括品牌、尺寸、价格、配置,这些应该作为属性封装在类里。可能需要一个商品类,比如Phone,包含品牌型号、尺寸、价格、配置这些字段。然后,入库的数量和总价可能需要另一个类来管理,比如库存类Inventory,用来记录各个商品的库存数量和总金额。 接下来,用户提到可以在控制台输入数量,所以需要考虑如何从控制台读取输入。Java中可以用Scanner类来处理。然后需要根据输入的数据更新库存,这里要注意输入的数据如何与具体的商品对应起来。比如,用户输入2和3,分别对应华为和小米的入库数量,所以程序需要明确这两个数字对应的商品。 然后,输出部分需要显示每个商品的详细信息,包括品牌、尺寸、价格、配置、库存数量以及该商品的总金额,最后是所有商品的总库存和总金额。这里可能需要遍历库存中的每个商品,输出其信息,并累加总库存和总金额。 另外,商品的总金额是单价乘以数量,所以在每次入库的时候需要更新该商品的总金额,同时累加到总金额中。库存类需要记录每个商品的库存数量,以及所有商品的总库存数和总金额。 可能的结构是:Phone类有品牌、尺寸、价格、配置四个属性。Inventory类包含一个Phone到库存数量和该商品总金额的映射,比如用HashMap<Phone, int[]>,其中int数组第一个元素是数量,第二个是该商品的总金额。或者,可能更清晰的是创建一个StockItem类,包含Phone实例、库存数量、该商品总金额,然后Inventory管理一个StockItem的列表。 不过,为了简化,可能直接在Inventory类中用两个数组或两个变量来分别存储华为和小米的库存,因为用户明确只有两种商品。但更好的做法是使用面向对象的方式,允许扩展更多的商品类型。所以,可能还是用集合来存储不同的商品及其库存信息。 接下来,考虑程序的流程:初始化两种手机的信息,创建Inventory实例,从控制台读取入库数量,更新库存,然后输出详细信息。 需要注意的是,价格和总金额都是浮点数,处理时可能会有精度问题,但在实际商业应用中通常用BigDecimal,不过用户给出的示例用了double类型,如3688.88,所以这里可能直接用double来处理,但要注意四舍五入的问题。 然后,具体步骤: 1. 创建Phone类,包含品牌、尺寸、价格、配置。 2. 创建Inventory类,管理多个Phone的库存,提供入库方法,计算总库存和总金额。 3. 主程序里初始化华为和小米的Phone实例。 4. 使用Scanner读取用户输入的两个整数,分别对应华为和小米的入库数量。 5. 调用Inventory的入库方法,更新库存。 6. 最后输出每个商品的详细信息,总库存和总金额。 可能的错误点:输入的顺序是否正确,比如第一个数字是华为,第二个是小米。用户示例中的入库数量是2和3,对应华为和小米,总价分别是7377.76(2*3688.88)和8966.64(3*2988.88),总金额是两者之和。所以必须确保输入顺序正确。 在代码中,可能需要将华为和小米的Phone实例按顺序处理,所以在读取输入时,第一个数字对应华为,第二个对应小米。 测试用例:输入2和3,总库存是5,总金额是7377.76+8966.64=16344.40。 现在,开始编写代码结构。 Phone类: 属性:brand(String),size(double),price(double),configuration(String) Inventory类: 属性:一个列表或Map来存储各个Phone及其库存数量和总金额。比如,可以用List<StockEntry>,其中StockEntry包含Phone对象,库存数量,该商品总金额。 或者更简单的,因为只有两种商品,可以用两个变量分别存储华为和小米的库存数量和总金额。但这样扩展性不好。更好的做法是使用集合。 所以StockEntry类可能包含: Phone phone; int quantity; double totalPrice; 然后Inventory有一个List<StockEntry> entries。 但为了简化,可能直接在Inventory中使用一个Map<Phone, StockEntry>,这样方便根据Phone查找对应的库存信息。 入库方法:接收Phone和数量,更新对应的StockEntry的数量和总金额。 然后,总库存数是所有StockEntry的quantity之和,总金额是各个totalPrice之和。 主程序中: 创建华为和小米的Phone实例。 然后,读取两个整数,假设第一个是华为的数量,第二个是小米的数量。 然后,调用Inventory的addStock方法,分别传入华为和对应的数量,小米和对应的数量。 然后输出时,遍历Inventory中的每个StockEntry,打印详细信息。 现在,编写代码的大纲: Phone.java: public class Phone { private String brand; private double size; private double price; private String configuration; public Phone(String brand, double size, double price, String configuration) { this.brand = brand; this.size = size; this.price = price; this.configuration = configuration; } // getters 方法 } StockEntry.java: public class StockEntry { private Phone phone; private int quantity; private double totalPrice; public StockEntry(Phone phone) { this.phone = phone; this.quantity = 0; this.totalPrice = 0.0; } public void addQuantity(int amount) { this.quantity += amount; this.totalPrice += amount * phone.getPrice(); } // getters } Inventory.java: import java.util.ArrayList; import java.util.List; public class Inventory { private List<StockEntry> stockEntries; public Inventory() { stockEntries = new ArrayList<>(); } public void addStock(Phone phone, int amount) { for (StockEntry entry : stockEntries) { if (entry.getPhone().equals(phone)) { // 需要Phone类正确实现equals方法 entry.addQuantity(amount); return; } } // 如果不存在,添加新的StockEntry StockEntry newEntry = new StockEntry(phone); newEntry.addQuantity(amount); stockEntries.add(newEntry); } public int getTotalQuantity() { int total = 0; for (StockEntry entry : stockEntries) { total += entry.getQuantity(); } return total; } public double getTotalAmount() { double total = 0.0; for (StockEntry entry : stockEntries) { total += entry.getTotalPrice(); } return total; } public List<StockEntry> getStockEntries() { return stockEntries; } } 主程序: import java.util.Scanner; public class Main { public static void main(String[] args) { Phone huawei = new Phone("华为", 5.5, 3688.88, "8+128G 全面刘海屏"); Phone xiaomi = new Phone("小米", 5.0, 2988.88, "4+64G 全面屏"); Inventory inventory = new Inventory(); inventory.addStock(huawei, 0); // 初始库存为0? inventory.addStock(xiaomi, 0); Scanner scanner = new Scanner(System.in); System.out.println("请输入华为手机的入库数量:"); int huaweiAmount = scanner.nextInt(); System.out.println("请输入小米手机的入库数量:"); int xiaomiAmount = scanner.nextInt(); inventory.addStock(huawei, huaweiAmount); inventory.addStock(xiaomi, xiaomiAmount); System.out.println("-------------库存明细-------------"); for (StockEntry entry : inventory.getStockEntries()) { Phone phone = entry.getPhone(); System.out.printf("品牌型号:%s 尺寸:%.1f 价格:%.2f 配置:%s 入库数量:%d 总价:%.2f%n", phone.getBrand(), phone.getSize(), phone.getPrice(), phone.getConfiguration(), entry.getQuantity(), entry.getTotalPrice()); } System.out.println("---------------------------------"); System.out.printf("总库存数:%d%n", inventory.getTotalQuantity()); System.out.printf("库存商品总金额:%.2f%n", inventory.getTotalAmount()); } } 不过,这里有几个问题需要处理: 1. Phone类的equals方法需要正确重写,否则在inventory.addStock时无法正确判断是否是同一个手机。因为用户的需求中,华为和小米是不同的实例,所以当在Inventory的addStock方法中查找是否存在该Phone时,默认的equals方法(比较对象地址)可能无法正确识别。因此,应该在Phone类中重写equals和hashCode方法,根据品牌、尺寸、价格、配置来判断是否相等。 但在这个案例中,用户可能只需要两种特定的手机,所以可能不需要动态添加其他型号。因此,可能可以直接在Inventory初始化时添加这两个手机,然后在入库时根据输入的顺序来分别处理。或者,在输入的时候,用户输入的两个数字分别对应华为和小米,所以不需要通过equals判断,而是直接按顺序处理。 这可能更简单。因为用户明确要处理华为和小米两种,所以可以不需要用Map来查找,而是直接按顺序处理。例如,库存中有两个固定的条目,华为和小米,按顺序添加数量。 这样的话,代码可以简化。例如,Inventory类中维护两个StockEntry,一个华为,一个小米。或者直接在Inventory中使用两个变量。 这可能更直接,但扩展性不好。但根据用户的需求,可能足够。 或者,主程序中,在调用addStock时,直接按顺序处理输入的数量。例如,用户输入的两个数,第一个是华为,第二个是小米,那么在添加库存时,分别调用addStock(huawei, huaweiAmount)和addStock(xiaomi, xiaomiAmount),并且Inventory中的addStock方法会找到对应的条目。 但需要确保Inventory中存在这两个Phone的条目。因此,在初始化Inventory时,可能需要预先添加这两个手机,库存为0,或者当第一次调用addStock时自动创建条目。 根据之前的Inventory类设计,当第一次添加某个Phone时,会自动创建StockEntry。因此,在主程序中,可能不需要预先添加库存为0,而是在用户输入数量后,调用addStock方法,传入数量。例如: inventory.addStock(huawei, huaweiAmount); 如果Inventory中还没有这个Phone的条目,就会创建新的StockEntry,并添加数量。这样,初始库存为0的情况下,第一次添加数量就是入库数量。例如,如果初始库存是0,用户输入2,那么库存变为2,总价是2*价格。 但根据用户示例,入库数量是2和3,总价是7377.76和8966.64,这正好是2*3688.88和3*2988.88,所以初始库存是0,然后添加数量。这样设计是正确的。 但问题在于,如果用户多次运行程序,或者多次入库,每次都是新增数量,而不是设置数量。所以addStock方法中的addQuantity是正确的,因为它累加数量。 不过,在用户的需求中,可能每次运行程序都是一次独立的入库操作,所以不需要考虑多次入库的情况。但按照题目描述,“可以在控制台输入入库商品的数量”,可能意味着每次运行程序时输入的数量是当次入库的数量,总库存是该次入库后的结果。例如,运行程序,输入2和3,总库存是2和3,总金额是7377.76+8966.64。如果再次运行程序,输入1和1,那么总库存是1和1,而不是累加。或者,可能题目中的入库是每次入库的数量,总库存是累加的。但根据用户示例,入库数量是2和3,总库存是5,总金额是16344.40。所以可能需要将每次的输入视为新增数量,即库存是累加的。 不过,根据问题描述,可能程序每次运行都是一次独立的操作,即输入当次入库的数量,然后显示当前总库存(即当次入库后的数量)。或者,是否总库存是每次运行程序后的累加?这需要明确。但根据示例,入库数量是2和3,总库存数是5,所以程序应该将输入的数量视为当次要入库的数量,并显示入库后的总库存。 因此,Inventory中的addStock方法应该将传入的数量累加到现有库存中。例如,如果库存中已经有华为的2台,再次调用addStock(huawei,3),则总库存变为5。 但根据用户示例,当输入2和3时,总库存是5,所以可能程序每次运行都是单次入库操作,总库存是当次输入的数量。或者,可能程序中的库存是每次运行独立计算的,即每次运行程序时,初始库存为0,输入的数量就是当次的入库数量,总库存等于输入的数量之和。例如,用户输入2和3,总库存是5,总金额是2*3688.88 +3*2988.88。 根据用户提供的示例,总价是7377.76和8966.64,这正好是2*3688.88和3*2988.88,所以程序中的库存数量是当次入库的数量,而不是累加。因此,可能程序中的库存数量是当次输入的数值,而并不是累加历史记录。因此,每次运行程序时,输入的数量是当次要入库的数量,总库存就是这些数量的总和。 因此,在Inventory中,每次addStock时,是设置数量还是累加数量? 根据用户示例,入库数量是2和3,总库存是5,总金额是两商品各自的数量乘单价之和。所以,如果用户运行程序,输入2和3,库存数量是2和3,总库存是5。如果再次运行程序,输入1和1,库存数量是1和1,总库存是2,总金额是3688.88+2988.88=6677.76。 这表明,每次运行程序时,输入的数量是当次入库的数量,程序中的库存是当次的数量,而不是累加。因此,Inventory中的库存数量应该是当次添加的数量,而不是累加。所以,在addStock方法中,应该设置数量为传入的值,而不是累加。 但用户问题中要求的是“模拟商品入库的程序”,可能入库是多次的,但这里可能简化为每次运行程序进行一次入库操作,并显示当前总库存。或者,可能用户希望每次入库的数量是累加的,但根据示例,总库存是2+3=5,所以可能程序中的库存是每次输入的数量的总和,即每次运行程序时,输入的数量会被累加到库存中。 但示例中的总库存是5,而用户给出的入库数量是2和3,所以可能程序中的库存是累加的。因此,Inventory中的addStock方法应该将传入的数量加到现有库存中。 但根据示例,入库数量是2和3,总库存是5,总金额是这两个数量乘以单价的总和。因此,如果库存初始为0,然后addStock(2)和addStock(3),那么库存数量就是2和3,总和是5。这说明每次运行程序时,输入的数量是当次新增的数量,而程序中的库存是这些数量的总和。因此,Inventory中的addStock方法应该将数量累加。 因此,在代码中,StockEntry的addQuantity方法应该将传入的amount加到现有的quantity上。这样,如果多次调用addStock,数量会累加。 但用户的问题可能希望每次运行程序时,输入的是当次入库的数量,而程序显示的是当前仓库中的总库存。例如,第一次运行输入2和3,总库存是5。第二次运行输入1和1,总库存是6。但程序作为一次执行,可能无法保存状态,所以每次运行都是独立的。因此,可能用户的问题中,每次运行程序都是独立的一次入库操作,即输入的数量是当次要入库的数量,总库存就是这些数量的总和,而不是历史累加。例如,输入2和3,总库存是5,总金额是两者的总和。而再次运行程序时,输入1和1,总库存是2,总金额是3688.88 + 2988.88=6677.76。 这可能更符合示例的情况,因为用户给出的总库存数是5,总金额是16344.40,这正好是2和3的数量之和。因此,在程序中,库存数量就是当次输入的数量,而不是历史累加。所以,Inventory中的addStock方法应该设置数量为传入的值,而不是累加。 但是,这样的话,如果多次调用addStock,后面的调用会覆盖前面的值。例如,如果先调用addStock(huawei,2),然后调用addStock(huawei,3),那么库存数量是3,而不是5。 这显然不符合用户示例中的情况,因为用户示例中的入库数量是2和3,总库存是5,所以需要累加。 这里可能存在矛盾,需要明确用户的需求。根据问题描述,“可以在控制台输入入库商品的数量,最后打印出仓库中所有商品详细信息以及所有商品的总库存数和库存商品总金额。”这里的入库操作是单次还是多次?例如,用户可能希望程序允许用户多次输入入库数量,直到选择退出,然后显示总库存。但根据问题描述,可能是一次性输入当次的入库数量,然后显示总库存。因此,每次运行程序时,用户输入的是当次要入库的数量,程序显示入库后的总库存,即总库存等于当次输入的数量之和。 例如,用户运行程序,输入2和3,程序显示总库存5,总金额16344.40。再次运行程序,输入1和1,显示总库存2,总金额6677.76。这种情况下,Inventory在每次运行时都是新的,初始库存为0,然后添加当次的数量。 因此,在程序中,每次运行都是独立的一次入库操作,库存初始为0,用户输入的数量被添加到库存中,最终显示总库存是输入的数量之和。 因此,Inventory中的addStock方法应该将传入的数量设置为当次入库的数量,或者累加到现有库存中? 根据用户示例,入库数量是2和3,所以华为的库存是2,小米是3,总库存5。这表明,当次入库的数量是2和3,所以程序中的库存数量就是这两个数字。因此,Inventory中的addStock方法应该将传入的数量设置为当前库存,而不是累加。但这样的话,如果程序允许多次入库(比如在一个运行周期内多次输入),则每次输入会覆盖之前的库存。不过,根据问题描述,程序可能只需要一次输入,然后显示结果,因此,在代码中,直接将用户输入的数量作为当次入库的数量,设置库存为这些值。 因此,Inventory中的addStock方法应该设置库存为传入的数量,而不是累加。例如: 在StockEntry类中: public void setQuantity(int amount) { this.quantity = amount; this.totalPrice = amount * phone.getPrice(); } 然后,在Inventory的addStock方法中,找到对应的StockEntry,并设置数量。 但这样,如果多次调用addStock,最后一次调用会覆盖之前的数量。 或者,用户可能希望每次入库是增加库存,而不是设置。例如,第一次入库2台华为,第二次入库3台,总库存是5。但根据问题描述中的示例,可能用户希望当次入库的数量是2和3,总库存是这两个数的总和,而不是多次入库的结果。因此,在程序中,当用户运行程序时,输入的数量是当次要入库的数量,总库存就是这些数量的总和,而无需考虑之前的库存,因为程序不保存状态。 因此,正确的做法是将用户输入的数量作为当次入库的数量,直接设置为库存的数量,而不是累加。因此,在代码中,每次调用addStock时,设置库存为传入的数量,而不是累加。 但这样的话,如果用户多次调用addStock,比如先加2,再加3,总库存会是3,而不是5。这可能不符合用户示例。 看来这里存在歧义,必须根据用户提供的示例来判断。用户示例中的入库数量是2和3,总库存是5,所以华为和小米的数量分别是2和3,总库存5。因此,程序中的库存数量是用户输入的数值,而总库存是它们的总和。因此,正确的做法是将用户输入的数量作为当次入库的数量,直接设置到库存中,即库存数量等于输入的数量。因此,每次运行程序时,用户输入的数量是当次入库的数量,库存显示这些数量的总和。 这种情况下,Inventory中的addStock方法应该设置库存为传入的数量,而不是累加。例如: 在StockEntry类中: public void setQuantity(int amount) { this.quantity = amount; this.totalPrice = amount * phone.getPrice(); } Inventory的addStock方法: public void addStock(Phone phone, int amount) { for (StockEntry entry : stockEntries) { if (entry.getPhone().equals(phone)) { entry.setQuantity(amount); return; } } StockEntry newEntry = new StockEntry(phone); newEntry.setQuantity(amount); stockEntries.add(newEntry); } 这样,每次调用addStock(phone, amount)时,会设置该phone的库存为amount,而不是累加。 但用户示例中的总库存数是5,即2+3,这表示华为和小米的数量分别是2和3,所以总库存是它们的总和。如果Inventory中的addStock方法是将传入的数量设置为该phone的库存,而不是累加,那么这符合用户示例。例如,用户输入2和3,调用addStock(huawei, 2)和addStock(xiaomi,3),库存数量分别是2和3,总库存5。 因此,这样的设计是正确的。 综上,代码中的addStock方法应设置库存数量为传入的amount,而不是累加。因此,StockEntry的setQuantity方法会计算总价。 因此,StockEntry类中的方法应该是setQuantity,而不是addQuantity。 现在,调整代码: StockEntry.java: public class StockEntry { private Phone phone; private int quantity; private double totalPrice; public StockEntry(Phone phone) { this.phone = phone; this.quantity = 0; this.totalPrice = 0.0; } public void setQuantity(int quantity) { this.quantity = quantity; this.totalPrice = quantity * phone.getPrice(); } // getters... } Inventory.java中的addStock方法: public void addStock(Phone phone, int amount) { for (StockEntry entry : stockEntries) { if (entry.getPhone().equals(phone)) { entry.setQuantity(amount); return; } } StockEntry newEntry = new StockEntry(phone); newEntry.setQuantity(amount); stockEntries.add(newEntry); } 这样,当调用inventory.addStock(huawei, 2)时,华为的库存数量设置为2,总价为2*3688.88=7377.76。同样,小米设置为3,总价为3*2988.88=8966.64。总库存数是5,总金额16344.40,符合用户示例。 但是,这样设计的话,如果多次调用addStock,后面的调用会覆盖前面的值。例如,如果先调用addStock(huawei,2),再调用addStock(huawei,3),库存数量会是3,而不是5。这在用户示例中是正确的,因为用户示例中的入库数量是2和3,总库存是5,即两个不同的商品的库存相加。 因此,这样的设计符合用户的需求。 接下来,处理Phone类的equals方法。由于在Inventory的addStock方法中,需要通过Phone对象来判断是否已经存在该商品的库存条目,因此需要正确实现equals和hashCode方法。否则,默认的equals方法(比较对象引用)会导致无法正确识别相同的手机型号。 例如,如果在主程序中创建了huawei和xiaomi对象,然后在调用addStock时,每次传入的是同一个对象,那么equals会比较引用,从而正确找到对应的StockEntry。但在当前代码中,主程序中的huawei和xiaomi是固定的,因此在Inventory的stockEntries中,对应的Phone对象是同一个,所以即使没有重写equals方法,也能正确找到。例如: Phone huawei = new Phone(...); inventory.addStock(huawei, 2); inventory.addStock(huawei, 3); // 这会找到之前创建的StockEntry,并设置数量为3,覆盖之前的2。 但如果Phone类的equals没有正确重写,而用户创建了新的Phone实例,例如: Phone huawei1 = new Phone("华为",5.5,3688.88, "..."); Phone huawei2 = new Phone("华为",5.5,3688.88, "..."); inventory.addStock(huawei1,2); inventory.addStock(huawei2,3); // 这会认为这是两个不同的Phone,从而创建两个StockEntry。 这显然不符合预期。因此,为了正确判断两个Phone对象是否代表同一商品,必须重写equals和hashCode方法,根据品牌、尺寸、价格、配置来判断是否相等。 因此,在Phone类中,需要添加: @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Phone phone = (Phone) o; return Double.compare(phone.size, size) == 0 && Double.compare(phone.price, price) == 0 && Objects.equals(brand, phone.brand) && Objects.equals(configuration, phone.configuration); } @Override public int hashCode() { return Objects.hash(brand, size, price, configuration); } 这样,当两个Phone对象的品牌、尺寸、价格、配置相同时,被认为是同一个商品,从而在Inventory中会合并到同一个StockEntry中。 不过,在用户的需求中,华为和小米的配置不同,所以它们的Phone实例是不同的,这符合预期。 综上,现在的代码应该可以正确处理用户的示例。 测试运行: 输入华为数量2,小米数量3。 库存条目: 华为:数量2,总价7377.76 小米:数量3,总价8966.64 总库存5,总金额16344.40 输出应该如示例所示。 因此,代码是正确的。 最后,主程序中的Inventory初始化可能不需要预先添加StockEntry,因为当调用addStock方法时,如果不存在,会自动添加。 但在用户示例中,总库存数是当次输入的数量之和,因此代码是正确的。 综上,完整的Java代码如下:</think>以下是用Java实现库房货物入库管理的完整代码,分为四个类文件: ```java // Phone.java public class Phone { private String brand; private double size; private double price; private String configuration; public Phone(String brand, double size, double price, String configuration) { this.brand = brand; this.size = size; this.price = price; this.configuration = configuration; } // Getters public String getBrand() { return brand; } public double getSize() { return size; } public double getPrice() { return price; } public String getConfiguration() { return configuration; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Phone phone = (Phone) o; return Double.compare(phone.size, size) == 0 && Double.compare(phone.price, price) == 0 && brand.equals(phone.brand) && configuration.equals(phone.configuration); } @Override public int hashCode() { return Objects.hash(brand, size, price, configuration); } } // StockEntry.java public class StockEntry { private Phone phone; private int quantity; private double totalPrice; public StockEntry(Phone phone) { this.phone = phone; } public void setQuantity(int quantity) { this.quantity = quantity; this.totalPrice = quantity * phone.getPrice(); } // Getters public Phone getPhone() { return phone; } public int getQuantity() { return quantity; } public double getTotalPrice() { return totalPrice; } } // Inventory.java import java.util.ArrayList; import java.util.List; public class Inventory { private final List<StockEntry> entries = new ArrayList<>(); public void addStock(Phone phone, int quantity) { for (StockEntry entry : entries) { if (entry.getPhone().equals(phone)) { entry.setQuantity(quantity); return; } } StockEntry newEntry = new StockEntry(phone); newEntry.setQuantity(quantity); entries.add(newEntry); } public int getTotalQuantity() { return entries.stream().mapToInt(StockEntry::getQuantity).sum(); } public double getTotalAmount() { return entries.stream().mapToDouble(StockEntry::getTotalPrice).sum(); } public List<StockEntry> getEntries() { return new ArrayList<>(entries); } } // WarehouseApp.java import java.util.Scanner; public class WarehouseApp { public static void main(String[] args) { Phone huawei = new Phone("华为", 5.5, 3688.88, "8+128G 全面刘海屏"); Phone xiaomi = new Phone("小米", 5.0, 2988.88, "4+64G 全面屏"); Inventory inventory = new Inventory(); Scanner scanner = new Scanner(System.in); System.out.print("请输入华为手机入库数量: "); inventory.addStock(huawei, scanner.nextInt()); System.out.print("请输入小米手机入库数量: "); inventory.addStock(xiaomi, scanner.nextInt()); System.out.println("\n-------------库存明细-------------"); for (StockEntry entry : inventory.getEntries()) { Phone p = entry.getPhone(); System.out.printf("品牌: %s 尺寸: %.1f 价格: %.2f 配置: %s\n入库数量: %d 总价: %.2f\n", p.getBrand(), p.getSize(), p.getPrice(), p.getConfiguration(), entry.getQuantity(), entry.getTotalPrice()); } System.out.println("---------------------------------"); System.out.printf("总库存数: %d\n", inventory.getTotalQuantity()); System.out.printf("库存总金额: %.2f\n", inventory.getTotalAmount()); } } ``` ### 运行效果示例 ``` 请输入华为手机入库数量: 2 请输入小米手机入库数量: 3 -------------库存明细------------- 品牌: 华为 尺寸: 5.5 价格: 3688.88 配置: 8+128G 全面刘海屏 入库数量: 2 总价: 7377.76 品牌: 小米 尺寸: 5.0 价格: 2988.88 配置: 4+64G 全面屏 入库数量: 3 总价: 8966.64 --------------------------------- 总库存数: 5 库存总金额: 16344.40 ``` ### 程序特点 1. **面向对象设计** - `Phone`类封装商品基本信息 - `StockEntry`类管理单品库存信息 - `Inventory`类实现库存管理核心逻辑 2. **扩展性强** 通过重写`equals`和`hashCode`方法,支持后续添加新商品型号 3. **数值精确性** 使用`double`类型处理金额,满足常规精度需求(生产环境建议使用`BigDecimal`) 4. **交互友好** 控制台输入提示清晰,输出排版工整 5. **健壮性** 使用`stream`进行集合操作,代码简洁且不易出错 可以通过修改`Phone`类的属性和增加新的`Phone`实例来扩展支持更多商品类型。
阅读全文

相关推荐

zip
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 松下电工数字压力传感器用户手册详细介绍了DP-100系列数字压力传感器,涵盖其技术参数、操作方法及适用场景等,适用于各类需要精准压力测量的工业环境。 双屏显示:主屏与输出动作同步,可同时显示当前值和基准值,便于实时监控与调整。显示屏为12段字母数字显示,数字清晰易读。 三色指示:屏幕颜色随传感器状态变化(红、绿、橙),便于快速判断工作状态。 紧凑结构:尺寸仅□30mm,适合空间狭窄的安装环境。 多种操作模式:提供RUN模式(日常操作)、菜单设定模式(深入设置如输出模式切换)及PRO模式(高级功能如应差调整、复制设定)。 安全认证:DP-101(A)/102(A)型号通过特定认证,确保产品安全可靠。 复制功能:可通过数据通信将主传感器设定内容复制到其他传感器,减少人工设定错误,节省时间。 高性能传感:具备高精度,分辨率1/2,000,反应时间2.5ms(最长5,000ms可调),温度特性±0.5%F.S.,重复精度±0.1%F.S. 电子元件吸附检测:监测吸盘是否成功吸附电子元件。 总压力监测:测量管道或容器内的压力水平。 空气泄漏检测:通过压力变化检测泄漏情况。 DP-101□:适用于低压环境(-100kPa至100kPa)。 DP-102□:适用于高压环境(0kPa至1MPa)。 订购时需根据实际需求选择合适型号,考虑传感器的适用范围和工作条件。手册提供详细订购流程及注意事项,包括相关认证信息(如韩国S标志)。 复制功能:通过数据通信将主传感器设定复制到其他传感器,支持多种设定模式,避免设定错误,节省时间。 操作模式:RUN模式用于日常监控,菜单设定模式用于深入设置,PRO模式提供高级功能。 使用前需仔细阅读手册,了解各功能使用方法。遵循安全指南,正确安装和使用传感器,避免损坏。对于

最新推荐

recommend-type

超简单Android集成华为HMS Scankit 扫码SDK实现扫一扫二维码

【超简单Android集成华为HMS Scankit 扫码SDK实现扫一扫二维码】 本文将详细介绍如何在Android应用中轻松集成华为HMS Scankit SDK,实现高效稳定的二维码扫描功能。华为HMS Scankit SDK提供了强大的扫码能力,即使...
recommend-type

C++经典扫雷开发项目和安装包

这是一款用 C++ 开发的经典扫雷项目,适合 C++ 爱好者与初学者。资源包内有详尽代码注解、完整源码及 12 种游戏必备图像素材,覆盖雷区标志等。教程从设计原理讲起,细到代码结构、实战部署,涉及初始化地图、随机布雷、统计邻近雷数、图像加载、事件处理与胜负判定等。开发环境建议用 Visual Studio ,需安装 EasyX 图形库,项目配置为多字节字符集。
recommend-type

松下电工数字压力传感器操作手册

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 松下电工数字压力传感器用户手册详细介绍了DP-100系列数字压力传感器,涵盖其技术参数、操作方法及适用场景等,适用于各类需要精准压力测量的工业环境。 双屏显示:主屏与输出动作同步,可同时显示当前值和基准值,便于实时监控与调整。显示屏为12段字母数字显示,数字清晰易读。 三色指示:屏幕颜色随传感器状态变化(红、绿、橙),便于快速判断工作状态。 紧凑结构:尺寸仅□30mm,适合空间狭窄的安装环境。 多种操作模式:提供RUN模式(日常操作)、菜单设定模式(深入设置如输出模式切换)及PRO模式(高级功能如应差调整、复制设定)。 安全认证:DP-101(A)/102(A)型号通过特定认证,确保产品安全可靠。 复制功能:可通过数据通信将主传感器设定内容复制到其他传感器,减少人工设定错误,节省时间。 高性能传感:具备高精度,分辨率1/2,000,反应时间2.5ms(最长5,000ms可调),温度特性±0.5%F.S.,重复精度±0.1%F.S. 电子元件吸附检测:监测吸盘是否成功吸附电子元件。 总压力监测:测量管道或容器内的压力水平。 空气泄漏检测:通过压力变化检测泄漏情况。 DP-101□:适用于低压环境(-100kPa至100kPa)。 DP-102□:适用于高压环境(0kPa至1MPa)。 订购时需根据实际需求选择合适型号,考虑传感器的适用范围和工作条件。手册提供详细订购流程及注意事项,包括相关认证信息(如韩国S标志)。 复制功能:通过数据通信将主传感器设定复制到其他传感器,支持多种设定模式,避免设定错误,节省时间。 操作模式:RUN模式用于日常监控,菜单设定模式用于深入设置,PRO模式提供高级功能。 使用前需仔细阅读手册,了解各功能使用方法。遵循安全指南,正确安装和使用传感器,避免损坏。对于
recommend-type

冰激励振动理论图(FV)

冰激励振动理论图(FV)
recommend-type

C#实现多功能画图板功能详解

根据给定的文件信息,我们可以从中提取出与C#编程语言相关的知识点,以及利用GDI+进行绘图的基本概念。由于文件信息较为简短,以下内容会结合这些信息点和相关的IT知识进行扩展,以满足字数要求。 标题中提到的“C#编的画图版”意味着这是一款用C#语言编写的画图软件。C#(发音为 "C Sharp")是一种由微软开发的面向对象的高级编程语言,它是.NET框架的一部分。C#语言因为其简洁的语法和强大的功能被广泛应用于各种软件开发领域,包括桌面应用程序、网络应用程序以及游戏开发等。 描述中提到了“用GDI+绘图来实现画图功能”,这表明该软件利用了GDI+(Graphics Device Interface Plus)技术进行图形绘制。GDI+是Windows平台下的一个图形设备接口,用于处理图形、图像以及文本。它提供了一系列用于2D矢量图形、位图图像、文本和输出设备的API,允许开发者在Windows应用程序中实现复杂的图形界面和视觉效果。 接下来,我们可以进一步展开GDI+中一些关键的编程概念和组件: 1. GDI+对象模型:GDI+使用了一套面向对象的模型来管理图形元素。其中包括Device Context(设备上下文), Pen(画笔), Brush(画刷), Font(字体)等对象。程序员可以通过这些对象来定义图形的外观和行为。 2. Graphics类:这是GDI+中最核心的类之一,它提供了大量的方法来进行绘制操作,比如绘制直线、矩形、椭圆、曲线、图像等。Graphics类通常会与设备上下文相关联,为开发人员提供了一个在窗口、图片或其他表面进行绘图的画布。 3. Pen类:用于定义线条的颜色、宽度和样式。通过Pens类,GDI+提供了预定义的笔刷对象,如黑色笔、红色笔等。程序员也可以创建自定义的Pen对象来满足特定的绘图需求。 4. Brush类:提供了用于填充图形对象的颜色或图案的对象,包括SolidBrush(实心画刷)、HatchBrush(图案画刷)、TextureBrush(纹理画刷)等。程序员可以通过这些画刷在图形对象内部或边缘上进行填充。 5. Fonts类:表示字体样式,GDI+中可以使用Fonts类定义文本的显示样式,包括字体的家族、大小、样式和颜色。 6. 事件驱动的绘图:在C#中,通常会结合事件处理机制来响应用户操作(如鼠标点击或移动),以实现交互式的绘图功能。程序员可以通过重写控件的事件处理函数(例如MouseClick, MouseMove等)来捕获用户的输入并作出相应的绘图响应。 7. 画布变换:在GDI+中,可以通过变换Graphics对象来实现平移、旋转和缩放等效果,这对于实现更复杂的绘图功能是非常有用的。 由于没有具体的文件名称列表,我们无法从这方面提取更多的知识点。但根据标题和描述,我们可以推断该文件名称列表中的“画图板”指的是这款软件的名称,这可能是一个与GDI+绘图功能相结合的用户界面程序,它允许用户在界面上进行绘画和书写操作。 总结以上内容,我们可以了解到C#编程语言与GDI+结合可以创建出功能丰富的画图应用程序。开发人员能够利用GDI+提供的丰富API实现复杂的图形操作,提供用户友好的界面和交互体验。这不仅有助于提高软件的图形处理能力,同时也能够满足设计人员对于高质量视觉效果的追求。
recommend-type

超参数调优:锂电池预测模型优化的不传之秘

# 摘要 本文针对锂电池预测模型的优化进行了系统性的研究,深入探讨了理论基础、超参数调优的策略与技巧,并实践了在锂电池预测模型中的应用。通过理论分析与实验验证,本文揭示了超参数与模型性能之间的关系,并探讨了多种超参数优化方法。同时,本文提供了针对锂电池预测模型的性能评估方法,识别并解决了过拟合与
recommend-type

青龙面板怎么搭建

<think>我们正在回答用户关于如何在服务器上搭建青龙面板的问题。根据用户提供的引用,我们有多个不同的安装方法,主要使用Docker进行部署。我们将综合这些引用,给出一个清晰、步骤详细的安装教程。 注意:青龙面板是一个支持Python3、JavaScript、Shell、TypeScript的定时任务管理平台,常用于运行各种脚本。 我们将按照以下步骤进行: 1. 准备环境:确保服务器已安装Docker和Docker Compose。 2. 创建目录并下载配置文件(如果使用docker-compose方式)。 3. 运行容器。 4. 访问面板并进行初始化配置。 由于引用中有
recommend-type

全面深入掌握应用密码学第二版精华

### 知识点概述 **标题**:Applied Cryptography PART1 **描述**:《应用密码学第二版》是一本全面的密码学资料,它涵盖密码学的基础知识和高级应用,对于想要深入理解并运用密码学的读者来说,是一个宝贵的资源。 **标签**:Applied Cryptography 密码 应用 **压缩包子文件列表**:APPLYC12.pdf、APPLYC11.pdf、APPLYC3.pdf、APPLYC4.pdf、APPLYC2.pdf、APPLYC5.pdf、APPLYC13.pdf、APPLYC6.pdf、APPLYC14.pdf、APPLYC9.pdf ### 知识点详细说明 #### 密码学基础 密码学(Cryptography)是研究信息加密和解密的数学原理和计算方法的学科。在《应用密码学第二版》中,可能涉及以下基础知识: 1. **对称密钥加密**:使用相同的密钥进行加密和解密,如AES(高级加密标准)和DES(数据加密标准)算法。 2. **非对称密钥加密**:使用一对密钥(公钥和私钥),公钥加密信息,私钥解密,如RSA算法。 3. **哈希函数**:一种单向加密函数,将任意长度的数据映射到固定长度的值,如SHA-256和MD5。 4. **数字签名**:利用非对称密钥加密原理,用于验证消息的完整性和来源。 #### 密码学的应用 **应用密码学**涉及到将密码学原理和技术应用到实际的安全问题和解决方案中。在该书籍中,可能会探讨以下应用领域: 1. **网络安全**:包括SSL/TLS协议,用于保护互联网上的通信安全。 2. **区块链技术**:密码学在区块链中的应用,如工作量证明(Proof of Work)和非对称密钥。 3. **安全存储**:如何使用加密技术安全地存储数据,例如在数据库中的加密技术。 4. **安全协议**:在不同计算平台间交换加密信息的协议,例如IPSec。 #### 密码学进阶主题 进阶主题可能包括: 1. **密码学中的数学基础**:素数、群、环、域以及椭圆曲线等数学概念。 2. **密码分析**:研究攻击加密系统的方法,包括已知明文攻击、选择明文攻击等。 3. **量子密码学**:探讨量子计算对当前加密算法的影响,以及量子安全的加密技术。 #### 文档内容细节 从压缩包子文件列表来看,文档内容可能按照章节或主题进行分割,例如: - **APPLYC12.pdf** 和 **APPLYC11.pdf** 可能涵盖了密码学的基础知识和基本概念。 - **APPLYC3.pdf** 和 **APPLYC4.pdf** 可能讨论了对称加密算法以及实现的案例和方法。 - **APPLYC2.pdf** 和 **APPLYC5.pdf** 可能深入讲解了非对称加密技术,如RSA算法。 - **APPLYC13.pdf** 和 **APPLYC6.pdf** 可能包含了哈希函数和数字签名的详细描述。 - **APPLYC14.pdf** 和 **APPLYC9.pdf** 可能介绍了密码学在网络安全、区块链、安全存储和安全协议中的应用实例。 ### 结论 《应用密码学第二版》作为一本全面的密码学参考书,不仅为读者提供了密码学的基础理论知识,还深入探讨了这些理论在现实世界中的具体应用。通过阅读这本书籍,读者将能够更好地理解密码学的原理,并学会如何在实际中运用这些知识来解决安全问题。特别是对于那些希望在信息安全领域深造的学习者来说,该书无疑是一份宝贵的资源。通过对压缩包子文件列表的分析,我们可以看到这本书覆盖了广泛的加密算法和技术,使其成为密码学爱好者的必读之作。
recommend-type

LSTM网络结构选择指南:让锂电池寿命预测更准确

# 摘要 长短期记忆网络(LSTM)作为一种特殊的循环神经网络(RNN),近年来因其在序列数据处理上的卓越性能受到广泛关注。本文首先介绍了LSTM网络的基础知识及在锂电池寿命预测中的应用概述。随后深入探讨了LSTM的理论框架、关键技术、网络结构选择与优化。文中详细分析了锂电池寿命预测的数据处理流程、模型
recommend-type

大物公式

<think>首先,用户意图是查找大学物理相关公式,用户问题是“大学物理常用公式汇总”。我需要根据任务要求进行网络搜索,整合内容,生成回答。 任务要求关键点: - 调用网络搜索工具进行检索。 - 整合内容,生成详细、清晰、实用、可操作的回答。 - 禁止将所有引用内容集中在回答末尾;引用应该分散在回答中。 - 避免使用第一人称(如“我”)。 - 避免步骤词汇(如“首先”、“然后”)。 - 组织答案为多个方法或步骤,每个步骤间换行。 - 对于公式和代码:行内公式用$ $,独立公式用$$ $$;代码用三个反引号注明语言。 - 回答后添加“§§相关问题§§:”部分,列出至少3个相关问题,基于用户问题