Acme Produce Warehouse雇佣您编写一个简单的赢博体育程序来跟踪他们的水果和蔬菜库存。每天一开始,办公室就会收到一份报告,说明目前库存的各种产品有多少箱。在每个工作日,卡车送来新鲜的农产品,卡车带着农产品离开。每当一辆卡车到达或离开时,办公室就会收到一份报告,显示每种产品在该卡车上进出的数量。有了赢博体育这些信息,办公室就可以确定一天结束时库存的农产品数量。
你被要求编写一个程序,在一天结束时自动计算库存水平。该程序将在收集当天到达和离开病例的赢博体育信息后每天运行一次。您的程序将从名为“stock.txt”的文本文件中读取所需的赢博体育信息,该文件包含有关当天开始时库存的农产品数量以及每种农产品在当天到达和离开的数量的信息。下面是一个典型的stock.txt文件:
高汤苹果高汤生菜高汤橙子高汤番茄洋葱高汤西兰花高汤土豆高汤橙子10苹果10西兰花10洋葱50土豆12番茄8番茄
每一行都以一个单词开头,该单词告诉您该行是报告当天开始的库存水平、出货还是出货。每行上的第二个项标识了所讨论的产品的种类,第三个项是数量的整数计数。在编写程序时,您不应该假设仓库中储存的产品种类,因为这可能会随着时间的推移而改变。例如,葡萄没有出现在上面的列表中,因为葡萄是一种季节性商品,只在一年中的特定时间储存。
你的工作是编写一个程序,从stock.txt文件中读取信息,并在一天结束时使用它来构造和打印股票报告。例如,给定上面文件中的信息,程序应该打印
苹果,生菜,橙子,西红柿,洋葱,西兰花,土豆,土豆
对于我们的解决方案,我们需要创建两个类。第一个类是一个简单的类,它记录一种产品的库存水平。
公共类项目{私有字符串名称;私有int数量;public Item(String name) {this.name = name;数量= 0;}}
我们最终将需要向该类添加其他方法。
接下来,我们需要一个类来跟踪仓库的全部物品库存。
公共类库存{私有数组列表<项目>库存;public Inventory() {stock = new ArrayList<Item>();}}
我们还需要向这个类添加方法——在下面的部分中,我们将开始确定我们需要哪些方法。
编写面向对象程序的一个重要部分是决定我们需要向每个类添加什么方法。一种非常有效的策略叫做自顶向下设计。在这个策略中,我们快速勾画出我们需要的关键类,然后开始为我们的程序编写主方法。在编写主方法的过程中,我们将发现我们的类需要一些方法来完成这项工作。
下面是我们的产品跟踪程序的主要方法。
public static void main(String[] args){扫描器输入= null;try {input = new Scanner(new File("stock.txt"));} catch(Exception ex) {ex. printstacktrace ();system . exit (0);}库存I = new Inventory();while(input. hasnext()){//从文件中读取并处理一行输入。字符串命令= input.next();字符串produce = input.next();int case = input.nextInt();if(command.equals("stock")) {I.addItems(produce,cases);} else if(command.equals("in")) {I.addItems(produce,cases);} else if(command.equals("out")) {I.removeItems(produce,cases);}} I.printReport();}
在这个方法中,驱动动作的主要因素是我们必须处理的数据文件的结构。正如您在这里看到的,main方法中的大部分逻辑都是读取stock.txt文件中各个行所必需的代码。txt中的每一行都将导致我们必须从库存中添加或删除物品:这将导致我们向库存类添加addItems()和removeItems()方法。最后,问题声明说,我们需要在处理stock.txt文件后生成一个报告。那份报告应该列出我们赢博体育的库存产品以及每种产品的数量。由于Inventory类拥有关于库存物品的赢博体育信息,因此它应该负责打印该报告:因此我们决定向该类添加printReport()方法。
一旦我们确定了在Inventory类中需要三个新方法,我们就可以开始编写这些方法了。
第一种方法将给定产品的一定数量的箱子添加到库存中。这个方法必须计算出我们是否已经在库存中有那个项目。如果我们这样做,我们只需要找到描述该项目的Item并增加其案例数。如果我们的库存中没有该物品,我们将需要创建一个新的item对象并将其添加到库存中。
public void addItems(String item,int howMany){//当一些物品进入时,我们首先需要查看这些物品是否已经在我们的库存列表中if(exists(item)) {item existingItem = find(item);existingItem.increaseQuantity(多少);} else {Item newItem = newItem (Item);newItem.increaseQuantity(多少);stock.add (newItem);}}
这个方法需要回答的一个关键问题是我们是否已经有给定的商品库存。为了帮助我们做到这一点,我将向Inventory类添加一个额外的助手方法。exists()方法将获取产品的名称,并确定我们的库存列表中是否有该产品的item对象。
private boolean exists(String name) {for(int n = 0;n < stock.size();n++) {Item i = stock.get(n);if(i.s ismyname (name))返回true;}返回false;}
Helper方法通常被声明为私有的,因为它们用于类中的其他方法。
addItems()还需要使用第二个辅助方法,find()方法,它可以在库存列表中搜索具有给定名称的Item:
private Item find(String name) {for(int n = 0;n < stock.size();n++) {Item i = stock.get(n);if(i. ismyname (name))返回i;}返回null;}
我们需要添加到库存类的下一个方法是removeItems()。
public void removeItems(String item,int howMany) {item existingItem = find(item);existingItem.decreaseQuantity(多少);if(existingItem. isnonleft ()) {stock.remove(existingItem);}}
该方法还可以利用find()帮助器方法来快速查找我们需要处理的Item。
最后,这里是printReport()方法的代码。
public void printReport() {for(int n = 0;n < stock.size();n++) {Item i = stock.get(n);System.out.println(我);}}
该方法使用了Java中常用的技术。如果我们想让一个类具备使用println()或print()方法的能力,我们只需要在类中添加一个特殊的方法:该方法是toString()方法,它返回一个描述对象的String。
在为Inventory类编写必要方法的过程中,我们发现Item类需要几个新方法。下面是Item类的最终版本,其中包含了使一切正常工作所需的附加方法:
公共类项目{私有字符串名称;私有int数量;public Item(String name) {this.name = name;数量= 0;}公共布尔isnonleft(){如果(数量== 0)返回true;否则返回false;}公共布尔isMyName(字符串名称){如果(this.name.equals(name))返回true;否则返回false;}公共无效的增加数量(int n){数量+= n;}公共无效的减少(int n){数量-= n;}公共字符串toString(){返回名称+ ":" +数量;}}