整个题目难度不大,但由于其也算是一个有些复杂的系统(并且需求文件很凌乱),因此在理解题意上花了一点时间。
最后进行了梳理,整个项目需要做的事情如下:
0. 程序结构
共六个类:
1. 主类Main,用于封装main函数。
2. Inventory类,用于封装程序的业务逻辑。
3. 四个handler类,分别封装四种事务处理的函数。
Main类代码:
package com.codesocean;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
Inventory inventory = new Inventory();
} catch (IOException e) {
e.printStackTrace();
}
}
}
1. Inventory类的结构设计
Ⅰ 原理介绍
使用BufferedReader拓展FileReader,可以实现逐行读取。
通过BufferedReader,将Transactions和Inventory中的数据全部读入到内存中。
之后再依次处理事务即可。
2. ADOR四个业务处理类的编写
Ⅰ 原理 + 具体实现
考虑到程序的代码结构,我选择将四种业务逻辑的处理分别分装到四个类当中,提高代码结构化的同时也增加了程序的可拓展性。
目前的需求文件中,只需要四个业务处理函数即可,于是我将业务处理函数写成静态方法,可以直接从类调用。
以Ahandler类为例,只需要传入要处理的一条transaction,并且传入内存中Inventory信息的容器即可。方法会将新的货物信息添加到Inventory容器中。
package com.codesocean.handlers;
import java.util.ArrayList;
public class Ahandler {
public static void handle(String[] transaction, ArrayList arrInventory){
arrInventory.add(new String[]{transaction[1],"0",transaction[2],transaction[3]});
}
}
其余业务处理函数的思路基本一致。
3. Inventory类中的业务流程
Ⅰ 原理 + 具体实现
Inventory类中要做的就是针对剩余的未处理的transaction分别调用相应的事务处理函数,同时在处理结束后将这条transaction删除。
//Handle the A transactions;
for (int i = 0; i < arrTransactions.size(); i++) {
if (arrTransactions.get(i)[0].equals("A")) {
Ahandler.handle(arrTransactions.get(i), arrInventory);
arrTransactions.remove(i);
i--;
}
}
这里我选择使用for循环遍历所有transactions,值得注意的是,当每删除一个transaction时,需要将i-1。
这里千万不要使用for-each。Java中的for-each,其迭代器位于对象内,且仅有一个。多重for-each会导致迭代器冲突。且与大多数语言相同,Java中for-each的迭代器与删除元素也不相容。
在处理O事务时,需要根据出货量大小先提前对所有O事务进行排序。这里我使用了Java自带的sort函数,通过实现comparator()接口完成。
//Sort the O transactions
arrTransactions.sort(new Comparator() {
@Override
public int compare(String[] o1, String[] o2) {
if (o1[0].equals("O") && o2[0].equals("O")) {
return (Integer.parseInt(o1[2]) - Integer.parseInt(o2[2]));
} else {
return -1;
}
}
});
4. 输出文件
输出文件直接使用BufferedWriter即可,但值得注意的是,在写完后必须同时关闭BufferedWriter和FileWriter,否则无法正常写出。
Inventory.java
package com.codesocean;
import com.codesocean.handlers.Ahandler;
import com.codesocean.handlers.Dhandler;
import com.codesocean.handlers.Ohandler;
import com.codesocean.handlers.Rhandler;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
public class Inventory {
Inventory() throws IOException {
String baseUrl = "E:\\学校资料\\第三学期事项\\Java程序设计\\JavaExperiment\\EXP3\\java exp 3\\data\\";
BufferedReader inventory = new BufferedReader(new FileReader(baseUrl + "Inventory.txt"));
BufferedReader transactions = new BufferedReader(new FileReader(baseUrl + "Transactions.txt"));
FileWriter sfw = new FileWriter(baseUrl + "Shipping.txt");
BufferedWriter shipping = new BufferedWriter(sfw);
FileWriter efw = new FileWriter(baseUrl + "Errors.txt");
BufferedWriter errors = new BufferedWriter(efw);
FileWriter ifw = new FileWriter(baseUrl + "newInventory.txt");
BufferedWriter newInventory = new BufferedWriter(ifw);
ArrayList arrInventory = new ArrayList<>();
ArrayList arrTransactions = new ArrayList<>();
ArrayList arrShipping = new ArrayList<>();
ArrayList arrErrors = new ArrayList<>();
String newLine = "";
while ((newLine = inventory.readLine()) != null) {
String[] arr = newLine.split("\t");
arrInventory.add(arr);
}
while ((newLine = transactions.readLine()) != null) {
String[] arr = newLine.split("\t");
arrTransactions.add(arr);
}
//Handle the A transactions;
for (int i = 0; i < arrTransactions.size(); i++) {
if (arrTransactions.get(i)[0].equals("A")) {
Ahandler.handle(arrTransactions.get(i), arrInventory);
arrTransactions.remove(i);
i--;
}
}
//Handle the R transactions;
for (int i = 0; i < arrTransactions.size(); i++) {
if (arrTransactions.get(i)[0].equals("R")) {
Rhandler.handle(arrTransactions.get(i), arrInventory);
arrTransactions.remove(i);
i--;
}
}
//Sort the O transactions
arrTransactions.sort(new Comparator() {
@Override
public int compare(String[] o1, String[] o2) {
if (o1[0].equals("O") && o2[0].equals("O")) {
return (Integer.parseInt(o1[2]) - Integer.parseInt(o2[2]));
} else {
return -1;
}
}
});
// for (int i = 0; i < arrTransactions.size(); i++) {
// for (String j : arrTransactions.get(i)) {
// System.out.print(j + "\t");
// }
// System.out.print("\n");
// }
try {
//Handle the O transactions
for (int i = 0; i < arrTransactions.size(); i++) {
if (arrTransactions.get(i)[0].equals("O")) {
Ohandler.handle(arrTransactions.get(i), arrInventory, arrShipping, arrErrors);
arrTransactions.remove(i);
i--;
}
}
} catch (Exception e) {
}
//Handle the D transactions
for (int i = 0; i < arrTransactions.size(); i++) {
if (arrTransactions.get(i)[0].equals("D")) {
Dhandler.handle(arrTransactions.get(i), arrInventory, arrErrors);
arrTransactions.remove(i);
i--;
}
}
for (int i = 0; i < arrInventory.size(); i++) {
for (int j = 0; j < arrInventory.get(i).length; j++) {
newInventory.write(arrInventory.get(i)[j] + "\t");
}
newInventory.write("\n");
}
for (int i = 0; i < arrShipping.size(); i++) {
for (int j = 0; j < arrShipping.get(i).length; j++) {
shipping.write(arrShipping.get(i)[j] + "\t");
}
shipping.write("\n");
}
for (int i = 0; i < arrErrors.size(); i++) {
for (int j = 0; j < arrErrors.get(i).length; j++) {
errors.write(arrErrors.get(i)[j] + "\t");
}
errors.write("\n");
}
newInventory.close();
ifw.close();
shipping.close();
sfw.close();
errors.close();
efw.close();
}
}
Ahandler.java
package com.codesocean.handlers;
import java.util.ArrayList;
public class Ahandler {
public static void handle(String[] transaction, ArrayList arrInventory){
arrInventory.add(new String[]{transaction[1],"0",transaction[2],transaction[3]});
}
}
Dhandler.java
package com.codesocean.handlers;
import java.util.ArrayList;
public class Dhandler {
public static void handle(String[] transaction, ArrayList arrInventory, ArrayList arrErrors) {
for(int i = 0 ; i < arrInventory.size() ; i ++) {
if(transaction[1].equals(arrInventory.get(i)[0])) {
if(!arrInventory.get(i)[1].equals("0")) {
arrErrors.add(new String[]{"0",transaction[1],arrInventory.get(i)[1]});
} else {
arrInventory.remove(i);
}
}
}
}
}
Ohandler.java
package com.codesocean.handlers;
import java.util.ArrayList;
public class Ohandler {
public static void handle(String[] transaction, ArrayList arrInventory, ArrayList arrShipping, ArrayList arrErrors) throws Exception {
for(int i = 0 ; i < arrInventory.size() ; i ++) {
if(transaction[1].equals(arrInventory.get(i)[0])) {
if(Integer.parseInt(arrInventory.get(i)[1]) < Integer.parseInt(transaction[2])) {
arrErrors.add(new String[]{transaction[3],transaction[1],transaction[2]});
throw new Exception();
}
arrInventory.get(i)[1] = Integer.toString(Integer.parseInt(arrInventory.get(i)[1]) - Integer.parseInt(transaction[2]));
for(int j = 0 ; j < arrShipping.size() ; j ++) {
if(arrShipping.get(j)[0].equals(transaction[3]) && arrShipping.get(j)[1].equals(transaction[1])) {
arrShipping.get(j)[2] = Integer.toString(Integer.parseInt(arrShipping.get(j)[2]) + Integer.parseInt(transaction[2]));
return;
}
}
arrShipping.add(new String[]{transaction[3],transaction[1],transaction[2]});
return;
}
}
}
}
Rhandler.java
package com.codesocean.handlers;
import java.util.ArrayList;
public class Rhandler {
public static void handle(String[] transaction, ArrayList arrInventory){
for(int i = 0; i < arrInventory.size() ; i ++) {
if(arrInventory.get(i)[0].equals(transaction[1])) {
arrInventory.get(i)[1] = Integer.toString(Integer.parseInt(arrInventory.get(i)[1]) + Integer.parseInt(transaction[2]));
}
}
}
}
Main.java
package com.codesocean;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
Inventory inventory = new Inventory();
} catch (IOException e) {
e.printStackTrace();
}
}
}