一.实验目的
1.掌握Java中文件的读写操作。
2.学会使用Java提供的实用类(Vector, ArrayList)来完成特定的功能。
3.掌握字符串类(String, StringBuffer)的使用。
4.掌握用面向对象的方法分析和解决复杂问题
二.实验内容(注意加粗)
- 编写一个Inventory.java完成以下功能
1.程序首先打开并读取Inventory.txt中记录的所有库存记录,然后读取Transactions.txt,处理这个文件中包含的事务,记录发货记录到Shipping.txt,并记录错误信息到Errors.txt中。最后更新库存到另外一个文件NewInventory.txt中。
2.文件Inventory.txt和NewInventory.txt的每行包含一个存货记录,没条记录包含下面一些字段息,这些字段之间用一个tab分开(见后面的文件格式):
字段 格式和含义
Item number | 字符串型 | 货物编号 |
---|---|---|
Quantity | 整型 | 货物数量 |
Supplier | 字符串型 | 供应商编号 |
Description | 字符串型 | 货物描述 |
- 3.字段Items按照从小到大的顺序写入文件的。注意Item号不必连续,如Item号为752的后面可能是800。
- 4.文件Transactions.txt包含几个不同的处理记录(每行一条记录)。每条记录前面以一个大写字母开头,表示这条记录是什么类型的事务。在不同的大写字母后面是不同的信息格式。所有的字段也是以tab键分开的(见Transactions.txt文件格式)。
- 5.以’O’开头的事务表示这是一个发货订单,即某一种货物应该发给特定的客户。Item number和Quantity的格式如上面表格定义。Custom编号和上面的Supplier编号一致。处理一条定单记录(以’O’开头的事务)意味着从减少库存记录中相应货物的数量(减少的数量=发货单中的数量),记录发货信息到Shipping.txt中。注意:Inventory.txt中的quantity不应该小于0,如果对于某一种货物,库存的数量小于发货单的数量的话,系统应该停止处理发货单,并记录出错信息到Errors.txt。如果对于某一种货物有多个发货单,而且库存总量小于这些发货单的总和的话,系统应该按照发货单中的数量从小到大的有限原则满足客户。也就是说,对于某一种货物如果一个数量Quantity少的发货单没有处理之前,数量Quantity多的发货单永远不会被处理。(这种处理原则不受发货单记录在Transactions.txt的先后顺序影响)
- 6.以’R’开头的事务表示这是一个到货单记录,在’R’后面是Item number和它的数量Quanlity。处理一条到货单意味着增加库存中相应货物的数量(增加的数量=到货单中的数量)。注意:如果在Transactions.txt文件中,到货单出现在发货单之后,到货单中的货物数量可以用来填补发货单中的数量(可以理解成在Transactions.txt中,优先处理到货单)。
- 7.以’A’开头的事务表示向库存中增加一种新的货物(即这种货物以前库存中没有),在’A’后面是Item number,供应商supplier以及货物的描述description。处理一个新增货物记录意味着向库存中增加一个数量Quantity为0的新的Item。你可以假设在一个Transactions.txt中,新增货物记录总是出现在第一个到货单之前。
- 8.以’D’开头的事务表示从库存中删除一种货物,在’D’后面是Item号。删除操作在所有的事物处理之后才被处理总是,以保证对于可能出现的同一种货物的发货单的操作能在删除之前被正确处理。如果要删除的某种货物的库存量Quantity不为0的话,系统应该向Errors.txt记录出错信息。
- 9.文件Shipping.txt中的每一行代表给某一客户的发货信息。Shipping.txt中的每一行分别是客户编号、Item号、货物数量,它们之间用tab键分隔。如果发货单中有两条客户编号和Item编号一样的记录,在Shipping.txt中应该将这两条发货信息合并(即将它们的数量相加)。
- 10.Errors.txt文件包含未发送的发货记录和库存量大于0的删除记录。Errors.txt每一行包含Custom编号、Item编号以及发货单上的数量Quantity。对于删除操作,Custom编号为0,数量Quntity为库存中的Quantity.
- 11.实验测试数据:
Inventory.txt
17 42 6 Widget,blue
1234 0 4 Whatsit
123123 999999 98 Doohicky
Transactions.txt
0 123123 1000 9
0 17 36 8
0 17 12 4
R 123123 1
D 1234
A 5 4 Thingy
系统可拆分为以下几个部分
输入
try (FileReader reader = new FileReader("Inventory.txt")) {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(reader);
while (scanner.hasNextLine()) {
temInventory.add(new Inventory(scanner.next(), scanner.nextInt(), scanner.next(), scanner.nextLine().trim()));
}
}
这里涉及到scanner的知识 (详情请见我的JAVA学习博客)
java.util.Scanner
帮助我们接受键盘数据
1.Scanner s = new Scanner(System.in)
2.接受用户的输入,可以直接返回相应的数据类型
String nextLine ();换行符分割 int next():空格分割
3.判断是否还有有效的输入 boolean hasNextXxx();
输出
FileWriter Shipping = new FileWriter("Shipping.txt");
for(int i =0;i<shippingList.size();++i) {
O tem_O = shippingList.get(i);
Shipping.write(tem_O.Customer_number+" "+tem_O.Item_number+" "+tem_O.Quantity+'\n');
}
Shipping.close();
writer写文件,没有文件则创建
靠+‘\n’ 换行
inventory.java(库存的货物)
package research;//包
public class Inventory implements Comparable<Inventory>{
public String Item_number;
public Integer Quantity;
public String Supplier_number;
public String description;
Inventory(String Item_number,Integer Quantity,String Supplier_number,String description){//构造函数
this.Item_number=Item_number;
this.Quantity=Quantity;
this.Supplier_number=Supplier_number;
this.description=description;
}
void out() {//检测输出
System.out.println(Item_number+" "+Quantity+" "+Supplier_number+" "+description);
}
@Override//检查
public int compareTo(Inventory o) {//重写compareTo用于后来的排序
// TODO Auto-generated method stub
if(this.Item_number.equals(o.Item_number)) {
return this.Quantity-o.Quantity;
}else {
return Integer.parseInt(this.Item_number)-Integer.parseInt(o.Item_number);
}
}
}
Transactions.java(事务)
package research;//包
import java.util.Scanner;
public interface Transactions {//接口
public static void read(Scanner scanner) {}
//对于四种不同的事物创建不同的class再分别进行实现接口
}
class O implements Transactions,Comparable<O> {//针对0创建的class
public String Item_number;
public Integer Quantity;
public String Customer_number;
public void read(Scanner scanner) {//实现接口
// TODO Auto-generated method stub
this.Item_number=scanner.next();
this.Quantity=scanner.nextInt();
this.Customer_number= scanner.nextLine().trim();
}
public O(String Customer_number,String Item_number,Integer Quantity) {//构造函数
// TODO Auto-generated constructor stub
this.Customer_number=Customer_number;
this.Item_number=Item_number;
this.Quantity=Quantity;
}
public O() {//无参构造函数
}
@Override
public int compareTo(O o) {//与上文同样,重写compareTo排序 因为货量小的优先发货
//什么鬼规定,我要是顾客得气死
// TODO Auto-generated method stub
if(this.Item_number.equals(o.Item_number)) {
return this.Quantity-o.Quantity;
}else {
return Integer.parseInt(this.Item_number)-Integer.parseInt(o.Item_number);
}
}
}
class R implements Transactions {//R
public String Item_number;
public Integer Quantity;
public void read(Scanner scanner){
this.Item_number=scanner.next();
this.Quantity= Integer.parseInt(scanner.nextLine().trim());
}
}
class A implements Transactions {//A
public String Item_number;
public String Supplier;
public String description;
public void read(Scanner scanner){
this.Item_number=scanner.next();
this.Supplier=scanner.next();
this.description= scanner.nextLine().trim();
}
}
class D implements Transactions {//D
public String Item_number;
public void read(Scanner scanner){
this.Item_number=scanner.nextLine().trim();
}
}
以上为class的构造,然后我们就可以开始写主函数
Main.java
package research;//包而已
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;//一大堆import
public class Main {
static List <Inventory> temInventory = new ArrayList<Inventory>();
static List <A> temA = new ArrayList<A>();
static List <R> temR = new ArrayList<R>();
static List <O> temO = new ArrayList<O>();
static List <D> temD = new ArrayList<D>();
static List <O> shippingList = new ArrayList<O>();
static List <O> errorsList = new ArrayList<O>();
static int n=0;//个人喜好,用set或者vector差不多,还是喜欢list
public static void main(String[] args) throws IOException, IOException {
try (FileReader reader = new FileReader("Inventory.txt")) {//读入inventory
@SuppressWarnings("resource")
Scanner scanner = new Scanner(reader);
while (scanner.hasNextLine()) {
temInventory.add(new Inventory(scanner.next(), scanner.nextInt(), scanner.next(), scanner.nextLine().trim()));
}
}
try (FileReader reader = new FileReader("Transactions.txt")) {//读入transaction
Scanner scanner = new Scanner(reader);
while (scanner.hasNextLine()) {
String tem=scanner.next();//开始分别实现read()接口然后压入list
if(tem.equals("0")) {
O tem_O = new O();
tem_O.read(scanner);
temO.add(tem_O);
}else {
if(tem.equals("R")) {
R tem_R = new R();
tem_R.read(scanner);
temR.add(tem_R);
}else {
if(tem.equals("D")){
D tem_D = new D();
tem_D.read(scanner);
temD.add(tem_D);
}else {
A tem_A = new A();
tem_A.read(scanner);
temA.add(tem_A);
}
}
}
}
}
//事务处理顺序A R O D不懂回去看题目加粗字体吧~
// for(int i =0;i<temO.size();++i) {
// System.out.println(temO.get(i).Item_number);
// }//留给你尝试玩玩?
for(int i=0;i<temA.size();++i) {//处理A
temInventory.add(new Inventory(temA.get(i).Item_number, 0,temA.get(i).Supplier, temA.get(i).description));
}
for (int i = 0; i < temR.size(); i++) {//R
for(int j =0;j< temInventory.size();++j) {
if(temInventory.get(j).Item_number.equals(temR.get(i).Item_number)) {
temInventory.get(j).Quantity+=temR.get(i).Quantity;
break;
}
}
}
Collections.sort(temInventory);
Collections.sort(temO);//升序排序
for(int i=0;i<temO.size();++i) {//O
O tem_O = temO.get(i);
for(int j = 0;j<temInventory.size();++j) {
if(temInventory.get(j).Item_number.equals(tem_O.Item_number)) {
if(temInventory.get(j).Quantity>=tem_O.Quantity) {
temInventory.get(j).Quantity-=tem_O.Quantity;
shippingList.add(new O(tem_O.Customer_number, tem_O.Item_number, tem_O.Quantity));
}else {//Error 处理
errorsList.add(new O(tem_O.Customer_number, tem_O.Item_number, tem_O.Quantity));
}
break;
}
}
}
for (int i = 0; i < temD.size(); i++) {//D
D tem_D= temD.get(i);
for(int j = 0;j<temInventory.size();++j) {
if(temInventory.get(j).Item_number.equals(tem_D.Item_number)) {
if(temInventory.get(j).Quantity==0) {
temInventory.remove(j);
}else {//Error 处理
errorsList.add(new O("0", tem_D.Item_number, temInventory.get(j).Quantity));
}
break;
}
}
}
for(int i =0;i<shippingList.size();++i) {//shipping重复相加
O tem_O = shippingList.get(i);
for(int j=i+1;j<shippingList.size();++j) {
if(tem_O.Customer_number.equals(shippingList.get(j).Customer_number)&&tem_O.Item_number.equals(shippingList.get(j).Item_number)) {
tem_O.Quantity+=shippingList.get(j).Quantity;
shippingList.remove(j);
--i;break;
}
}
}//开始索然无味的输出
FileWriter Shipping = new FileWriter("Shipping.txt");
for(int i =0;i<shippingList.size();++i) {
O tem_O = shippingList.get(i);
Shipping.write(tem_O.Customer_number+" "+tem_O.Item_number+" "+tem_O.Quantity+'\n');
}
Shipping.close();
FileWriter Errors = new FileWriter("Errors.txt");
for(int i =0;i<errorsList.size();++i) {
O tem_O = errorsList.get(i);
Errors.write(tem_O.Customer_number+" "+tem_O.Item_number+" "+tem_O.Quantity+'\n');
//System.out.println(tem_O.Customer_number+" "+tem_O.Item_number+" "+tem_O.Quantity);
}
Errors.close();
FileWriter NewInventory = new FileWriter("NewInventory.txt");
for(int i =0;i<temInventory.size();++i) {
Inventory tem_Inventory = temInventory.get(i);
NewInventory.write(tem_Inventory.Item_number+" "+tem_Inventory.Quantity+" "+tem_Inventory.Supplier_number+" "+tem_Inventory.description+'\n');
}
NewInventory.close();
//over
}
}
test
inventory
transaction
errors
shipping
NewInventory
以后有需求做一个有界面的算了